|
|
21:46 |
|
show
|
1:45 |
Hello and welcome to my course Python for Absolute Beginners I'm super excited to have you here we are going to have so much fun going through all of the code that we're going to write learning how to be effective with Python and honestly, learning how much fun programming can be.
If you're new to programming, don't worry you're actually in exactly the right place this course is for people who are new to programming.
A lot of courses assume background knowledge or experience with some programming concepts Do you know what a variable is?
Do you know what loops are?
Do you know what source code is?
Do you know what a compiler is?
Do you know how to use it?
And then they'll teach you the details of some language with this one, we're going to start right from the start that's what we mean by absolute beginners because we're beginning at the beginning.
We're going to cover all the ideas that maybe people who took computer science in college or have computer science degrees spent years studying, we're going to condense that down to just the essential things that you need to learn to have a core understanding of programming in general and we're going to work on Python and some of its most important features and teach you how to program simple applications with Python but don't let the word simple discourage you.
By the time you're done with this course you're going to be able to write meaningful programs that you can use to automate things in your life.
Are you a scientist and want to automate studying and processing the data you collect?
You'll be able to do that, no problem.
Need to create a simple little application to help you out with some other project you got going on?
Yes, you can do that, or do you want to use this as a springboard to get into the deeper programming concepts like web development, databases?
Yeah, it'll be great for that as well.
So again, welcome to the course I'm so happy to have you here, let's get started.
|
|
show
|
2:51 |
Let's start off with a question.
Should you be a programmer?
Sure, there's a bunch of people out there who love programming but it's probably not for everybody.
Or is it?
Well, let's look at it from a job perspective really quickly.
In 2020, it's estimated that there'll be one million computer-related jobs that go unfilled.
And often when you hear about policymakers talk about things like this, they say well what we need to do is train up a whole bunch of more computer scientists and send them out into the world so they can program all the things that need programming.
I think this actually misses the point of what programming can be and also makes it a much more narrow area of study.
It's not just about making a bunch of little programmers that can go out into the world and program the things and take all the jobs that we need to be filled.
No.
Programming is a superpower.
And it's applicable for many, many more people than they initially realize.
Here we have a little superhero who has some Python powers.
Notice that she has a Python bag from the Python conference she's carrying around.
What do I mean by programming is a superpower?
If you are a biologist, and you collect a bunch of data and you have tens of thousands of entries you got to go work with and it's more complicated than something like say, Excel could handle with.
Well, what do you do?
Hire a bunch of people to go through it?
Hire some grad students?
Or do you spend 10 minutes writing a little bit of Python code that within milliseconds can take all that data and generate the reports and give her the insights that she needs.
Or if you're an economist, and you need to do some work with a bunch of financial data?
Maybe you could make Excel do that maybe you could make some other software do it.
But with just a little tiny bit of programming power you can automate whatever it is you're trying to study in the financial markets and you'll be so far ahead of anyone else that's trying to do that same thing who is not a programmer.
So the perspective I want you to have throughout this course is that whatever you care about, are you in psychology?
Are you in biology?
Are you a physicist?
Are you in philosophy?
Yes, philosophers, it also applies as well.
Whatever you're into, if you learn a little bit of programming skill, you can take those mundane things that are hard to do, are tedious or take a long time or even maybe have too much data to even consider processing, with a little bit of programming experience you'll get in this course, you'll be able to go and automate that stuff and really supercharge whatever it is that you care about.
So, yeah, maybe the world needs more programmers but what it really needs is a bunch of people who have expertise in something, and then they have a little bit of programming experience to make them much much more effective.
Python's a really great place to get that power because it's so easy to get started with compared to other languages and there are many many libraries that we'll kind of talk about throughout this course that are super useful.
So, are you ready to be a superhero?
|
|
show
|
3:37 |
Does it seem like Python is everywhere?
Here's a cover story from TechRepublic.
Python is eating the world how one developer side project became the hottest programming language on the planet.
That guy you see in the background there his name is Guido van Rossum, and he created Python in 1990.
And it grew and grew and became a pretty respectable language it was doing important work until around 2012 where something happened and it just took off.
And really what the thing I think happened is Python started to be used much more broadly outside of the traditional web developer programming world.
Data scientists started moving there and all the types of folks I mentioned before with the superpower stuff, they saw Python having the right mix of what they need to get their work done and there are just more and more libraries hundreds of thousands of them actually created to solve all these problems.
So Python is just blowing up and becoming an extremely popular programming language.
How much, well let's go over this place called Stack Overflow.
If you're not a developer yet you might not be aware of what Stack Overflow is.
If you've done any programming at all, though you've been there.
Stack Overflow is a Q&A site for asking questions about very specific issues and questions and challenges you have with programming languages programming libraries, and so on.
Hundreds of thousands if not millions of questions many millions of visitors it's absolutely the first place you're going to find on the internet if you search for a detail about some programming language.
Over here, they have this cool thing called Stack Overflow trends.
And it shows the popularity or number of questions of the given programming language for that month.
You can go and you see this goes from 2009 to almost 2020, a little over 10 years of data.
And I put into this graph all the interesting programming languages C#, Python, JavaScript, Java, etc, etc.
Right, these are the mainstream programming languages that you might consider learning if you're like Hey, I want to get into programming but there's all these options, where should I start?" Well, this graph gives you a hint and a good place to start, doesn't it?
You don't have to be a mathematician to see that there might be one trend here and it's a little different than the others.
But let me highlight that for you.
If you look at Python, the growth of it is just exploding and it's becoming the most popular programming language in the world also the most popular way to learn programming at universities in the first place and this is really important because along with this curve here other things follow.
This means that there are tones of jobs in Python.
It also means there are many, many libraries that you can use to solve your problems.
For example, there are over 500 different libraries just to do genetics.
You don't have to start from scratch you can just say, I'd like to do this thing with genetics and there's probably some library out there you can go grab.
You find one of these languages that's down near the bottom it's very unlikely there are many, many different little libraries you're going to have to solve those problems from scratch yourself.
Though having a popular language is really important for lots of things but mostly because the tools and the libraries that you want to use, they're going to be great and plentiful.
Finally, if you want to read a little bit about it a data scientist over at Stack Overflow wrote a cool article called The Incredible Growth of Python.
And this was already evident back in 2017 you follow that graph back a little bit and you see, the big statement was well, it's starting to be more popular than these other languages, and we're projecting out that it's going to be pretty amazing.
And yet, their predictions are right this just keeps on going but if you want to dig into a little bit more this is quite an interesting article you can check out over there.
|
|
show
|
2:12 |
You should have a pretty good sense of what the prerequisite expectations are what we expect you to know as a student.
But let's just call them out really quickly here so you can be sure that you're in the right place.
First of all, there is no programming experience required.
Meaning, I'd say most programming courses out there expect that you have some programming experience and they just build on that right?
You already know how to program in Python so we're going to build a website in it.
Or you already know how to do this in JavaScript so we're going to build this interactive web thing with it.
This course is not like that.
We assume that you know nothing about programming we're going to take it nice and slow and make sure we set the right foundations for you so you can be successful with programming and with Python.
Obviously if there's no programming experience you also don't need to know Python.
So don't worry, if it's totally new to you it's an exciting place to be but you don't have to know anything about it.
So, that's fine.
You do need a desire to learn basic programming skills and of course we're going to learn those skills in Python but that would be translatable to other things.
So are you looking to gain this superpower that I mentioned at the beginning?
You should, because it will put you head and shoulders above all the other folks doing whatever it is that you care about.
So hopefully, you're excited to learn programming we're going to start with the basics and get that in place throughout this course.
However, you do need to be quote "good with computers" whatever the heck that means.
I would say, basically, you need to be able to type not necessarily super fast but typing is how you speak to the computer, how you create these programs and if typing is a challenge then this course is going to be super frustrating, right?
Programming in general is going to be very frustrating because all you do is type to the computer all day.
You'll hear a lot of professional programmers speaking poorly of things like user interfaces and mice, and all they do is use the keyboard all the time.
You can take that a little bit too far but certainly typing is important.
Also, operating a computer just in the sense of configuring things and installing stuff and so on.
You may have to set up Python or have to set up some other tools and editors and you just need to be able to work with a computer pretty decently.
So, I expect most people out there have this but I just want to put it out there like really this is the expectation that we have is that you are quote "good with computers".
|
|
show
|
4:53 |
What exactly are we going to cover in this course?
Well we're going to start talkin about why Python and why programming?
Well we actually just concluded that, didn't we?
Programming is a super power and Python is a great programming language that's easy to learn.
Put those together and you're off to a good start.
Next we're going to talk about how to get help.
Something that's really frustrating when you're getting started in programming is, things are not working.
You have to type exact, precise stuff to the computer.
It's not as hard as it sounds, but if it's not just right.
Not even just the words that you write but the order and the steps and the data.
If it comes unglued even just a little bit it's going to freak out and crash and not work.
And refuse to carry on.
That's frustrating when you're getting started because it's hard to know how to fix that.
Hard to know how to get help.
So there's a couple of options I have for you on how to get help, both self help and help through the course here.
We also want to make sure that your computer is ready to take this course, so we're going to talk about setup.
How do you get Python, the right version of Python installed?
As well as what editors you can use to write code and edit code throughout this course?
So we want to spend a little bit a time making sure everybody's setup and ready to take the course.
And then we get into the programming concepts proper.
We're going to talk about the big ideas of programming.
And what I mean by this is these are the ideas that you would learn from your first year computer science class if you went and took programming in the university.
But instead of spending a whole year in a class we're just going to spend a little bit a time and hit the high points.
But it's important that you have the right foundation to know how programs execute, what source code is how it gets translated to executable stuff, and so on.
Then we're going to start writing some code.
Writing your first line a code well we're going to write more than one line a code.
We're going to write a bunch a fun things but here we're going to start writing a little bit a code.
Visualizing what that does to the computer, both graphically and just runnin it to see what it does.
We'll get started there.
Then we're going to make our code interactive.
You can think of maybe different levels of complexity of writing code.
One of 'em is, I need to do something so do x and then do y and then do z.
Then you're done.
That's a real simple type a program but many programs don't work that way, do they?
If you open up your web browser, it interacts with you.
You type some stuff into the address bar and it goes somewhere.
Shows you some information.
That you click something.
It does somethin in response.
Maybe it asks you a question and then it does one of two things, depending on what you answer.
So making this interactive code, that either reads data and then makes a decision, or interacts with people and makes a decision.
Or more likely does both.
This is of course, where you need to be to write real software.
And so we're going to start writing simple code.
And then we're going to write this more interactive code with things like conditional statements and loops and so on.
Once you have the core ideas of a programming language in place, it's tricky to figure out how do I attack a problem?
You know I have this code I can write.
It makes the computer do stuff.
I have this problem.
It seems extremely complicated.
And I don't really know where to start.
But obviously people can solve it with software, so there must be some path.
But what I'm going to do is I'm going to give you a bunch of tips and techniques on how to break down the problem, so that it's not nearly as hard as it seems.
Ya know, a handful of techniques and we're going to do bunch of examples.
We're going to write a lot of code and talk through them and sort of think through the problem.
Here are a couple things we could do.
I'm going to choose this way and here's why, and so on.
We're also going to build a couple games during this course.
Games are fun and they're interactive.
And they can be nice and simple, but they also are pretty good stand ins for this making code interactive story, that I told you.
Right so, we'll try to have fun and write a couple a games and that'll challenge the things that we can do.
We're going to maybe have our game save stuff.
So we want to work with files and different file formats that our program can save and then remember, across running our program from time to time.
Things like leader boards and configurations files to let people extend the game without reprogramming it.
Stuff like that.
One of Python's really important powers is it has hundreds of thousands of external libraries that are extremely powerful.
I give you a hint about the geneticist earlier who could do, ya know, just go grab one of these libraries and ask some questions of data without actually working on all the details to make that happen.
So we're going to take a couple of external packages, apply them to some of the programs that we write and I'll show you where to go find many many more.
How to work with these external packages or libraries and add some really cool features to the programs that we write.
And that's it.
This is what we're going to do.
We're going to go dutifully through simple and then more complicated and more complicated code.
And add on little bits of super important functionality that, I think will actually be a whole lot of fun for you to learn as we go.
|
|
show
|
5:19 |
We're nowhere ready to start writing code yet.
We maybe don't even have Python or Editor set up.
I want to start right from the beginning talking about how do you get help.
Because who knows what stage of this whole process of learning Python and going through this course you might run into troubles.
So lets right up front talk about how you might get help either with a set up problem or with running some code.
So you go run your program and instead of something beautiful happening you get this.
I'm seeing lots of red little hyperlinks pointing at our files and at the bottom down here you see that there's this attribute error.
These are called exceptions.
And this is not good.
This means that your program has crashed and it's not running any more.
Notice how it says process finished with exit code 1.
That might sound good.
It's not good.
Zero is what you want.
If it's not zero, chances are it's bad.
So here we can see a little bit of details about this error.
We can see that the line of code that actually caused that problem text = text.lower() don't worry about what that means yet.
But that's the line where it crashed.
And then below it, there's a description of the error.
There's an attribute error.
NoneType object has no attribute lower.
This is actually I think is the most common error that you're ever going to run into in Python.
But there's many many of these.
So you're faced with this.
What do you do?
Or you're faced with Python won't install.
Or won't run your file or whatever.
Doesn't matter what the details are.
What do we do?
Well, first of all, you take exactly that error text and you put it into Google.
Maybe you've done this a bunch of times and you're totally comfortable with it but if you haven't tried this before it's ridiculously effective.
If there's some kind of error number oh man, sometimes that would be you just put in some random number into Google and it will give you exactly the solution that you need.
So yeah, just take that and put it straight into there.
Sometimes you want to be a little careful if it has very specific information about like your file name or something.
That can throw it off but generally put the error straight here.
And that will probably take you to stack overflow which is the place I was talking about before.
Here you can see somebody says Hey, I'm trying to predict this thing and I'm doing this but instead what I get is this attribute error.
And it's not on the screen here but if you scroll down they say Well here's the cause of this and here's what's happening.
And so the problem is you actually need to clean your data values because some of them they're not set and that's what's making it crash.
It's not a super solution they gave but it's a pretty good one.
It's hard to give the exact solution because it's such a general error.
Anyway, first thing, Google it.
The next thing is, if it's actually running we're going to have our editor.
This is the editor we're going to use.
If it's running, you can put it into a debugger and put a breakpoint.
See this line 29 here?
The main part of the screen where the little red dot is.
You click in that little area where the little red dot is it will toggle what's called a breakpoint.
And when you run your code it will stop there.
And look at all the gray on the screen by the code.
Now don't worry about what the code is.
But notice how it says like HTML is this big bunch of HTML stuff.
And Shoop is something and header is h1 Episode 220 machine learning in the cloud with Azure.
Those are the current values of all the pieces of data and variables you're working with.
Also, down here you can inspect what's happening and go step by step and down here you can even expand the values and interact with them and change them to see what effect that might have.
So if you're unsure what's happening maybe you're working with the value that's what you exactly expected.
You can put it in this debugger.
We're going to do this later.
Again, it doesn't have to make sense now.
I just want to make sure you have this right at the beginning in case you get stuck.
Another thing you can do.
After you've try to figure it out yourself and can't get this.
You can come over to the course repository on GitHub.
In the setup chapter, I'll give you details on how to get to this for this particular course but also on your course page when you're logged in the the website.
It's just a big link right at the top.
So, over here there's an issues section and maybe someone else has already had a problem that you've run into.
So here you can see a problem that's closed that somebody came here and said Hey, I'm having this problem with SSL certificate and I'm trying to do this thing to talk over the web with my Python program.
It looked like it worked in your video but then when I try it.
I get this.
And we have this little conversation and we figure out what the fix actually is.
So maybe if you go here and you see Closed issues or even Open ones but probably Closed ones you can actually see what happened.
Other students are running into and talking about that.
If you don't see something, you can ask a question just like this Hey, this is happening.
I not suer why.
Could you help?" Okay, so that's an option.
And then finally I have office hours where you can come and chat.
We can do screen sharing we can look at your programs.
See what's happening and so on.
So on your course page, you're have this section that says, "Come to our next office hour." If this isn't here that means one's not currently scheduled.
Maybe I'm away traveling or something like that.
But one will appear again here.
You can go to your account page and actually say Send me an email anytime a new office hour is scheduled.
You can go ahead and do that as well if you want.
But these are the four ways; Google it put it in the debugger if it's a programming run time thing check out the issues for the course repository page come to office hours.
I hope you don't get stuck at all but if you do I hope you get unstuck quickly.
|
|
show
|
1:09 |
Finally, before we wrap up this chapter I just want to introduce myself.
My name is Michael Kennedy, hello!
Here I am, this is what I look like.
You can find me on Twitter, where I'm @MKennedy.
Super excited to be putting this course together for you and happy you're in it.
So just a little bit about me I run the Talk Python to Me podcast.
This is a podcast that's been going for four or five years and I interview many of the influential folks in the Python industry, from the people who create Python to people who use it at places like Instagram as well as, say, astronomers who are using it to understand the stars.
So I have a pretty good spectrum of what people are doing and what they're up to with Python and how it's important to them and I'll try to convey that to you.
Also, I happen to run another podcast called Python Bytes.
This is like the weekly news in the Python space so if you want to stay up on that, you can subscribe to this.
Both of these give me a lot of different sources to draw from to share with you throughout this course.
Maybe most relevant, though is that I'm the founder and one of the principal authors at Talk Python Training, where you're taking this course.
So this is me, welcome to the course.
I'm happy to be here with you, let's get rolling.
|
|
|
14:35 |
|
show
|
3:06 |
In this chapter, we're going to make sure that your computer is ready for you to take this course.
We want to make sure that Python is set up you have some kind of editor that works well for the kind of code that we're going to write, and so on.
Let's start with Python.
You're going to need to have Python 3.6.
There's many different versions of Python and each time a new one is released they add a few features to the language.
That means code that is written for the most recent version of Python will not run on the older versions.
There's certain language syntax features that the older ones say, I have no idea what this is.
This doesn't work.
This is not Python.
Well, maybe it wasn't Python five years ago but it is now, so you need to have a modern one that understands what's going on.
And for this course you have to have Python 3.6 or above.
Higher is fine, but below that is not going to work.
So you might wonder, Do I have Python?
Did my computer already come with it?
Has it already been installed?
Did I install it a year ago and forget about it?
Well, let's find out.
On macOS or even on Linux, you can type Python3 -V, all one word Lowercase v means something entirely different.
Python3 -V and it will report out the version that it has so Python 3.7.4.
This is not the latest, but it is good enough because it's past 3.6.
Over on Windows, you type Python, not necessarily Python3.
There's different ways you can install Python on Windows.
Sometimes it comes with the Python3 command sometimes it doesn't.
So type, Python -V like before, and it will tell you the version.
Let's just play around with that really quick over here on my computer.
Now, something you're going to get familiar with is this thing called the terminal.
Now, there's a couple ways you can get to it.
If you're not a developer it's probably not hanging out down here in your dock like it is on mine and many developers'.
You can hit Command + Space and type terminal, on macOS.
We're going to talk about Windows in just a minute.
Or you could type this where you go applications, utilities, terminal.
But whatever, however you get to it I would pin it to your dock down here.
Again, we're going to talk about Windows in just a minute.
What you see here for macOS or really anytime for macOS it's exactly the same for Linux if you happen to be on Linux.
So, we're going to see do we have Python 3.
If we just type Python3 it does something that we don't want.
If we forget the three, well we get Python 2.7.
This is definitely not going to run the code that we want.
So, we don't want that.
We want to do Python3 -V and it records out that we have 3.7.5.
It's not the latest three that's out but plenty good so we're going to roll with it because it's 3.6 or higher that we need.
You know I also wonder where is this thing installed.
Where did it come from?
So you can ask which Python3, and it will show you it's installed over here.
Maybe that's useful if you're trying to track down I have multiple ones installed which one is it actually finding something like that.
So this is how you check whether you have Python on macOS and Linux.
Looks like I do.
|
|
show
|
2:57 |
Let's see how to verify that we have Python and the right version of Python on Windows.
We went to the terminal on macOS or on Linux and over here we're going to go to the Command Prompt.
And again, if you don't have it here you can just type startcmd and it's going to run like that.
This one has slightly different settings than that one.
That's a good question, why?
I honestly have no idea why.
So here we are, you'll see some kind of prompt like this with your username and you can type things like Python -V.
And over here, we have a newer version 3.8, how cool is that?
We could also try a Python3.
And look at this.
What the heck just happened there?
Why did we not see anything?
Well, it turns out, in the latest version or many of the recent versions of Windows 10 they've installed these little shims that if you try to run Python and it's not there it will suggest that you install it off the Windows 10 Store.
And that's a good way to get it.
You should consider that for sure.
But what's weird is, it doesn't say you don't have Python installed you should install it, or something when you do this.
If I just type Python3 notice, it opens up the Windows Store, and that's cool and I can just click install.
Oddly, this is 3.7 when 3.8 is out, but whatever.
3.7 is more than good enough you can install this and that would be great.
If you type Python or Python3 -V, like this and you get no output, not like this, but like this that means is just maybe kind of going to show you the Windows Store if you don't give it any options.
It should give you something here, even when you do this but it doesn't.
So, it can be really tricky like I just didn't get anything, right?
So, if you see something like this be sure to run it like that.
Now, we have Python installed here.
And we can actually ask where on macOS, which here we can ask where Python.
And it'll show you over in Python 3.8 this is apparently first in the path.
So that's the one that's going to run.
But we also have 3.7.
We also have the Windows app installed here.
And this is just the shim, the thing I talked about that launches the Windows Store.
But have the same question for Python 3 you can see it's over here and this other stuff you can ignore.
This one is some setup on but it's not first in the path so the Windows Store one is going to run first and then it will replace itself with real Python if you choose to install it.
Whew, does that seem a little bit complicated?
A little bit, but it's not too bad.
The thing is, you do this once, and you get it all set up and you're good to go.
So, just make sure that you have a command you can type that's either Python or Python 3 and you give it the -V, you get 3.6 or above.
If you want to install the Windows Store version that's totally fine.
If you do, the benefit is that you also have a Python3 command, unless you saw the Windows Store version.
Windows only has Python, not Python3.
It just happens to be it looks through the path and grabs the first one, which hopefully is Python 3 rather than two.
Okay, so make sure that you've got it set up so you can run this and get something along those lines on Windows, and then you'll be ready to take this course.
|
|
show
|
0:42 |
If it turns out that you don't have Python 3 or that the version is too low and you need to install a new version of Python 3 don't worry, it's pretty easy.
Folks over here at realPython.com have put together a nice guide for you.
So just visit realPython.com/installing-Python.
They let you identify your operating system.
Are you using Windows or Mac or Linux or whatever it is that you're using and then they give you a couple of different options and recommendation for the best way to install Python on your computer.
So you need to install Python instead of me giving you a whole bunch of variations and whatnot, this is a great article that gives you all that and a recommendation on what to do.
Just go check it out and then come back to the course.
|
|
show
|
4:40 |
In addition to Python you're going to need to be able to write code.
Now, truthfully, any text editor will let you write code but it is very important that you have one that understands Python and understands programming concepts because you'll be many, many more times effective and it'll catch all the errors for you.
You'll see what we mean throughout this course but I'm going to recommend a handful of editors that you could use, all of which are free and it's going to make you really much, much more comfortable and it'll catch the errors and help you out as you go.
So we're going to have a couple of levels of editing code.
We're going to start out just by playing with code in this thing called a REPL a Read Eval Print Loop, R-E-P-L.
Now, we actually saw that before when I was just trying to check if I had Python.
I typed Python3 without any extra stuff and I got something that looked kind of like this.
This is an interactive way where you can explore little bits of Python code.
You can see I said X is 10, Y is 98, Z is 24 and I multiplied them all together and got some kind of answer out.
This is not how we write normal computer code.
You can't save this.
You can't easily get this back.
So if you're going to write a real program you should save it to a file and then you feed that file to Python.
But in the very early stages of this course when we're just playing with simple, simple ideas we're just going to open this up and see what's happening.
Okay, so this is level one.
We're going to do this just for like a chapter or so and then I'm going to move on to writing real programs.
For that level, I'm going to be using something called PyCharm.
You already saw a screen shot of that.
Now, it says the Python IDE Integrated Development Environment for professional developers, and that is true.
Many professional developers use PyCharm.
It's extremely powerful and useful but it's also one of the most helpful editors for beginners as well.
The reason is it gives you all this help.
You're going, "I want to use this library," and you start to type it and it'll show you all the things you can do with it.
It'll give you automatic help.
It'll check for errors before you even run them and run into those problems, all kinds of great stuff.
So we're going to be using PyCharm.
There's a paid version, the Professional version and there's a free Community Edition.
We are going to be using the Community Edition.
If you have the Professional one, that's fine.
It's no harm with that, but you don't need to get it.
That one costs money.
The free Community Edition, as you can imagine, is free so we're going to be using that one and it's totally capable for what we need for this course.
The best way to get it is to install this thing called the JetBrains Toolbox.
So you can go download it.
I think you might have to log in.
I'm not entirely sure if you got to create an account or not.
But notice how it has PyCharm Professional in this list and then those are the installed ones.
If you scroll down farther, it says, "Available." Just scroll down until you see PyCharm Community.
Click that, and wait one minute and you'll have PyCharm.
What's nice about this is it always keeps it up to date and it gives you access to the other tools as well that you might need.
So it'll say, "Hey, there's an update for your PyCharm "You want to click here and get it?" Yes.
I do.
This is nice.
Make sure you install it and get going.
If, for some reason, you don't want to use PyCharm like I said, really nice, you'll see it super good.
I think it's the best editor for beginners.
If you don't want to use it for some reason the other good choice these days is something called Visual Studio Code.
This is free.
It is open source.
It is available on all the different platforms even though it's from Microsoft.
So you come over here.
You can see it, and it's a little under and the important thing is once you install it you also need to make sure you install the Python extension.
This thing has been downloaded 54 million times.
It's the most popular thing on Visual Studio Code but if you don't install it it's not going to understand Python and it's not going to work right.
Click this little box here.
It opens up this dialogue and it should have Python right at the top.
It seems like it's much more popular than all the others.
So click that, wait a few moments and you'll have your Visual Studio Code ready to work on Python.
Finally, there's one third option that you can consider.
I would recommend, really, PyCharm and then Visual Studio Code and then this, but there's a lot of folks especially coming from the data science world that like to work in something called JupyterLab or Jupyter Notebooks and you're welcome to use this, as well as the way to work with the course.
There's a few little situations where it won't quite work but for the most part, it'll be okay.
I'm not going to recommend this or use this but I will, at the very end of the course put an appendix if you want to install this.
It takes a few steps on configuring your system to make it work, and then you have this editor as well which is a interesting environment.
So you can use this for most of what you're doing and check the appendix on how to get going with that.
|
|
show
|
0:41 |
Now before we get started with this course I want to make sure that you have all the code that you're going to see written on the screen by me.
I'm going to make sure that everything that I write everything that I create is going to be saved and available for you, online, here on GitHub.
So at this address github.com/talkPython/Python-for-absolute-beginners-course If you go here and you somehow download this I'll show you a couple of options in a second.
If you download this, then you'll be able to have all the code that we've written.
This is also where those issues are where I told you, you can potentially go find other people who've solved problems like yours and so on.
So, before you go any farther make sure you go over to GitHub.
If you don't have an account, create one; you're going to want to have a GitHub account.
This is where all the software developers collaborate where you get all the libraries, all kinds of stuff.
And then just click that little star where it says unstar That's because I've already starred it.
Click that star and even maybe click fork so it goes over into your own space.
But most importantly you need to clone or download it.
So over here it says clone or download it gives you options to either use Git which I'll show you in a second, or just download a zip file and uncompress it.
The advantage of having Git is if there's any updates it will get the new updates over time, whereas the download by zip is just a snapshot of what it was at that moment.
Now before we move off this, let's really quickly get that code onto my machine.
So we're going to go over here and in this folder I'm going to git clone, that stuff.
So if you haven't used Git before you might need to install it.
So, you can see if you have it if you type "G-I-T".
Git.
If you get something like this, yay, you have Git.
You're probably good.
If you get an error, like command "Git Not Found" then just google and install Git for your operating system.
Install Git for macOS, install Git from Windows, whatever.
So what we're going to do is say git clone now I've copied the URL from the GitHub repository so, there's that.
And it's going to put it into this huge long folder here and that's going to make things not quite as easy for me so I'm going to override the folder it's going to create.
I'll just say, "beginners-course", like that.
If I hit go, it's going to go talk to it.
It's downloaded all the details and you can see here, there are just a couple of files.
Now when you actually do this, it will have all the code that I have not yet created, but I'm just about to.
So, I've created this so I can start putting code in here and saving it for you, but you should have more stuff of course, listed here because it will have everything I've already done in the future.
That's kind of cool.
|
|
|
2:29 |
|
|
36:01 |
|
show
|
2:29 |
Are you ready to cover the big ideas of computer programming and computer science?
We're going to try to go through them quickly.
After all, this is not a computer science course and definitely not a whole degree in it.
But there are a few things that you need to have a good conceptual understanding of.
Even if you can't get down to the details and work on them right away, that's fine.
But just a big conceptual understanding for some of these core ideas in computer programming and computer science.
We're going to start by talking about what is code and how does it execute?
Probably you've seen some code before but maybe you haven't.
And we're going to look at Python source code and compare it to a few other languages.
And then we're going to look deep inside the CPython runtime to see what happens when you create some Python source code and then you go through all the steps to turn that into an executing program.
Those steps for you are just say Python, run this application.
But there's a bunch of stuff happening that is good to know about.
It's good to have a conceptual understanding of course.
Next, we're going to talk about algorithms.
What are algorithms?
Cover a popular one.
How you learn about more.
How do you create or reuse an algorithm?
So we're going to talk a little bit about this idea of algorithms and tie that back to problem-solving a little bit more generally.
And then something super-important that I'm very excited to present right up near the front of the course is the difference between experts and beginner developers or professional and beginner developers, besides of course just getting paid.
How do they approach problem-solving?
How do they structure their code?
What are the various things that you need to go through or acquire as a beginner?
What skills do you need to acquire?
What mindset do you need to think about before you can make that transition over to expert developer?
So we're going to talk real briefly about some of those ideas and techniques and how you can get more information there.
And finally, one of the big ideas that we're not really covering in this chapter is data structures.
So algorithms and data structures, those are big big parts of thinking in computer science terms in addition to just knowing the programming language and the tools.
The reason we're not talking about data structures is because we're saving that for later in the course.
When we get deep into a program, we're going to start talking about the different data structures and using them together to start problem-solving.
So data structures is also one of the big ideas that belongs here but we're going to give it it's own special treatment later because it is really important.
|
|
show
|
2:39 |
What is source code?
Well, it's how we tell computers what to do.
It's the essential way the language in which we write computer software.
Now, when you look at some kind of application let's take a web app like this one here we have on the screen at Talk Python Training.
Some of this is just HTML.
Like in the top left, there's this microphone with a Python logo in it.
That is just an image.
It's just HTML and CSS stuff across the top HTML and CSS.
And you can debate whether or not that is really programming or not I'm going to say that it's maybe sort of but not really.
But then there's other stuff that's happening here that where the program, the web application and the server is making a decision and delivering information based on how you interact with it.
For example, have you logged in if you log in, it's got to verify that you have an account that the password is correct.
And things like that.
Going to set some information back into your browser so that it knows that when you come back the second and third and fourth page that you're still logged in who you are.
It's going to take some additional information.
There's different pages in the site.
This one courses slash details where you get to the general student page but some information that's passed to it.
This one is Python for .NET Developers the code is going to take that go and send it over to another server, the database and say, I want the course that corresponds to this.
And as long as it comes back it's going to show you this page with the details.
Now, here's some of the chapters that were sent back from that database.
You can see the title of chapter how long it is but notice also it's collapsed and grayed out.
The reason it's collapsing grayed out is the website this code decided this one you've actually already watched whoever's browser this is they've actually already watched those chapters so they're grayed out and collapsed So you can focus on what's next.
Given one of these chapters, for example object oriented Python It will show you the various lectures that are in there.
It'll indicate whether or not that lecture has subtitles both captions, there were that little book thing.
It'll gray these out based on which lectures you've watched.
So when you think about a computer program or you think about any kind of software at all it has to interact with data or with humans to it has to make these decisions and transform data.
And computer code is really just like English or French or German.
But for computers, we need to talk to it in a way that it can understand more accurately in a way that can be transformed into something that the computer understands.
|
|
show
|
5:56 |
Now let's look at a couple examples of simple, software code that you're going to write or could write, through this course.
What we have on the screen back here is a little bit complicated but it's not too bad.
And you know how you feel about that, we're going to get there but we're going to start much simpler than this.
The ideas we write in a very structured way to tell the computer what to do.
So here, is a very simple Python program or more accurately maybe a piece of a program.
It's what's called a function it says check_access and it takes this thing called an age.
Now idea is, we should be able to use this piece of functionality anywhere in our program to ask the current user whose logged in if we know their age, assuming that we do we can ask are they allowed to create an account are they allowed to access this part of our site or whatever.
So right at the beginning of that purple line with hash that is a comment, that's meant for us.
Much about writing software and computer code really has to do with writing for humans not writing for the machines.
Yes, of course, ultimately it's transformed for the machines but humans have to understand it and maintain it and it's read many more times than it's written so we need to write it in a way that's super clear.
So we have this thing of a function it's called check_access and given an age like 12 and it said no, no, no, no, we can't have anybody who is 13 or younger, using our service.
So we can send out a little message, right sorry you can't use this service and we can tell whatever other part of the program you did to use it, no, they're not allowed to do this.
In Python we say return False, so return the value give back the value whoever asked whether about you could use, this person can access this part, tell them no and we don't have yes or no we have true and false.
So if they're too young then we say, False.
But if we get past this check, if we're not true that they're less than 14 they must be, 14 or older.
So then we can return true, yes anyone who is 14 or older can use our service.
So, maybe you've not written a single line of Python yet maybe you have, but possibly haven't, even so spend a few moments with this I think you could make sense of it.
That's one of the really cool things about Python is it's actually pretty easy to understand.
Now they're very specific rules that we have to follow alright it has to be if with a space and then this test and then a colon and then indented, for the code that it's going to be within that case.
But once you learn the rules it's actually not too hard at all.
Well, that was Python.
Notice, it's the same thing up here in the left.
Let's look at a couple of other languages that has exactly the same behavior and I think what you'll notice is a lot of them have more symbol talk or they're much more verbose.
They all accomplish exactly the same thing but they're not necessarily as clear or simple as Python.
Next one we have here in the middle, is C++.
This language is, one of the core languages that build so many of the things that you use day to day.
Its been around since, I think the eighties it's based on a language called C which has been around even longer than that and Windows was built with that.
A lot of video games was built with that Linux was built with that either C or C++ and this is one of the, low level languages at least for software developers not necessarily for computers but you can see it does the same thing and notice on this one we have to say what kind of data is returned.
We have to say bool, check_access and we also have to say what type of data is accepted in integer.
Not a floating point number like 7.2 but seven, or eight.
And then of course this Boolean is also a true and false it's a very common idea.
Notice we have this if, basically the same test but there's a lot more, curly braces to indicate the ranges where parts running the blocks have code, and then there's semicolons to punctuate each line, C++.
This is common through many of the languages.
Over here we have visual basic.
Visual Basic is very very wordy and Python is also kind of wordy doesn't have as many symbols but for some reason the Visual Basic words just get in the way rather than clear things up so here you could explicitly say we have a function called check access we're going to pass the age by value which isn't integer and then it's going to return a thing which is a Boolean.
Whoo, that's a lot to write.
But none the less it means the same thing and we have another test.
If the age is less than 14 then we're going to tell you some other stuff.
Else, we're going to say, you know check access is false or check access is true the way you, return the indicated value and Visual Basic is to set the value of the thing you're running, the function.
We also have Javascript, this is very one of the more popular languages.
It runs in your browser it's the foundation of much of the interactive internet at least on the browser side of things.
Here we're going to create a things that's var check_access as a function that takes an age.
And again, from there on it's very very similar to the C++ side of things with curly braces, semicolons, and so on.
The way it actually runs is quite different.
And finally, we have C# this is the .NET Microsoft language along with VB as well.
And here we're going to have a program and a thing called a class and a public static function there's a lot of descriptors in this and the cases and scenarios which you can use them but other than that once you get through all this sort of wrapper stuff then you end up with just like Javascript just like C++ and do that test curly braces to describe the blocks semicolons to end the lines, and so on.
So, you can see a lot of commonalities but also a lot of differences amongst these different languages.
Python and VB are both more, word-driven they don't have as many things they don't have things like semicolons and curly braces but VB still defines all its blocks with like, closing type things like if and then then and then, and if, and so on.
So, it's similar but also different and then you can see the big influence with the C++, Java Script, and C#, with there C heritage curly braces, semicolons, and that sort of arrangement.
So here is the same program that piece of program, piece of functionality that we wrote before in five different languages.
|
|
show
|
2:49 |
How does code execute?
Well, we're going to focus of course on Python code and one of the things I have to do a lot I mean in a whole lot more than is reasonable I think is I need to take proper titles and convert these to either file names or the folder names as I'm developing these courses working on my podcast and so on.
And that can be a little bit error prone.
For example, if I want to take the phrase the title here How does a code execute?
That is not a valid thing I can put as a url because the question mark means something and these spaces aren't created and the capital H is kind of a problem.
So a reasonable thing to do would be to lower case everything drop the punctuation put dashes in between it that will work for file systems stuff like folders or even URLs as you might guest by the name.
Because I want to make this something I want to think about make it completely obvious and re-usable and maybe even compose-able I mixed it in with other scripts or something like that.
I wrote this program called urlfy and the way we run it is we say Python space urlfy.py and this is going to take this source code the Python code that I wrote in a file and then execute it.
Notice we have in the clipboard the title basically How does this code excute or how this code execute.
When I run it, a little title thing urlfy dash, dash, dash, dash comes out and says we're reading data from the clipboard so the program uses a library to access the macOS clipboarder, really in a clipboard and then it's just give you a null.
Okay, the thing we're going to turn into url format is how does code execute question mark and then it coverts it how to how doe code execute with dashes and lower case just like I described.
And because that was so fun and you always want to have a little break and a shoot day let's shoot out a few emojis three stars and like a little triple star farther in the distance.
And it's in the final message to the user copied to the clipboard and put a little emoji of a clipboarder something like that so we can just type this line and then whatever is in the clipboard is now transformed into this form that we can paste somewhere else.
So this is great.
This is super useful and this is actually something that is a great place to start when you're learning Python.
'Cause this little tiny utilities like you know what I do all day?
I've take this words and I turned them into subs that is valid to put in into folder names or file names.
Well, if you want you can write a little program so probably 15 lines to Python code and it does this automatically never making an error.
Super, super handy.
So the big question is what is actually happening here?
Sure, once we understand the Python codings they will run it at this line and this line and this line but there is actually a whole lot on going on.
Right, there's RAM and CPU instruction and all kind of interesting stuff happening.
So in this short section we're going to focus on what happens when we give Python some source codes and it actually runs it as a program.
|
|
show
|
4:23 |
So, we have our source code that we're going to talk about, but not yet.
And it's written into this file called urlify.py.
To run it, we just say, Python, here's some Python code.
Run this little application.
And we type this on our command prompt.
What happens next?
Well, obviously, we start out with the urlify.py file.
This is the Python source code.
And this is what most people think of as the thing that is running maybe right at the beginning.
But in fact, this is not what is run.
This is transformed several times into something else that then is actually run by Python.
So this is parsed or compiled by Python.
Basically, Python goes through and understands all the words and symbols and stuff in the source file and it converts it into a lower level thing that it doesn't have to try to interpret how you've written it.
It knows now there's an if statement.
Here's the thing we're testing, test it.
Stuff like that, like very simple, low level byte code that Python can use.
Now this step is not hugely expensive but it's not for free and you're reading potentially very large and complicated text files and turning them into this form that's been validated and there's a canonical representation of all the stuff in there.
So what happens next is this is actually saved into a local folder called double __pycache.
And the reason it does this is the next time you run this file second, third, and fourth time you run it Python can skip that first step.
And it goes, this file corresponds to this Python byte code.
We're just going to start from there and run it as a way to make sure it hasn't changed and things like that.
But it'll just grab this pre read pre understood version and start running that.
What does it do with this?
Well, it fires up the Python runtime or virtual machine.
Sometimes it's called a Python interpreter.
It's going to take this Python byte code and feed it to there and say Okay, what I want you to do is go through this step by step getting the data wherever you need it to get from.
Does it come off a file?
Do you ask the user?
Do you get it from a web service?
And use that to help make decisions and choose which byte instruction, bytecode piece to run next?
Usually, when you write some Python code like if this thing is greater than if the age is less than 14 that might turn into three or four different little instructions to make that test actually happen.
What Python going to do is it's going to take that byte code and it's going to feed it into a loop that just goes around and around and around and around, basically, endlessly as long as there's more byte code to be run.
And it's going to break it up into step by step by step and says, Okay, this step is to load up a value, age.
This step is to load up another value 14.
The next step is to test are the two loaded values less than equal less than each other.
Is the first one less than the second one.
And it just goes through things like that.
So it has this byte code it's going to break it up into little pieces.
Some of those might say we need to talk to the file system and go pull in some data from there.
To open a file stream and we're going to start working on that.
Some of it might create some memory structure that lives in RAM.
And it's going to read from it and write from it.
And that'll help it keep track of what it's doing.
So their code might say I also need to read from that thing let me go up there and see, you know what the name of the logged in user is, for example.
There's other stuff that happens to.
We don't have to explicitly say I need to create this place in RAM to put the data and then now I'm done with it.
Some languages actually do.
But Python automatically cleans it up.
So there's two levels of what is called garbage collection that just goes and throws away the data returns it back to the operating system.
If you're done using it.
Though, maybe I created the name of somebody got the name of the user, put it into HTML then I'm done with that variable.
Well, something has to give that memory back to the computer.
So there's some processes called garbage collection that take care of that.
This is only a small part of what happens when you run your Python code.
Code is also turned into this thing called a tree.
So that it can be understood in a more generalized way.
There's a lot of stuff going on.
But this is a pretty good mental model to have.
When you type Python my source code file what is happening, this step from left to right and that loop and loop and loop again and again and again.
Figure out what each byte code instruction says to do.
This is what happens when we run our code.
|
|
show
|
2:21 |
Here's our little check access functionality function that we had talked about previously.
And it is five lines of code here, if you ignore the blank lines in the comment which you can totally do that.
What would it look like if we were to try to visualize this in bytecode?
Now, the actually bytecode that Python uses is binary data.
It's like trying to print out a picture or a Word document or a ZIP file without decompressing it, using a tool that understands it it just is a bunch of ones and zeroes and it's kind of meaningless if you try to look at it directly.
But there's a way that we can say Python, show me the text representation of this as you understand it, so it basically becomes legible to us.
And if we do that, if we take this over we get something that looks a whole lot more like a bunch of little tiny steps no so much exactly like what we wrote here.
I just want to point out you do not need to remember this.
You definitely do not need to be able to tell us what each one of these pieces does or to create it yourself.
This is just so you have a sense of when I say, Python, run that, what actually happens.
What happens is it goes through that compilation parsing step that turns it from that source code through this tree structure, into this bytecode.
And then it saves those to a file and when you run it, it just runs 'em from top to bottom following the jumps as it might need to.
So it says things like load the age load the constant number 14 and then compare the two things that were loaded and if it's false, go to 20.
So 20 is return true.
Down at the bottom, you can see I've made that orange for you.
So what you write and what the program actually does step by step is not exactly the same.
There's a lower-level bit that's happening and, of course, this is still high-level.
This is not actually machine instruction zeroes and ones, assembly language-type of thing.
This is still higher than what is happening on the CPU but this is really how Python understands what you're doing and it can basically know the machine instructions to do each one of those steps to load paths, load confs, compare off and so on.
So when you run your code it first gets turned into this stuff and this is what actually runs.
Again, you don't have to be able to work with or create this bytecode, just so you have this working concept of what's actually happening when you run your program.
Well, it turns into bytecode and it processes them one at a time, from top to bottom unless there's a jump or some kind of way to move around in there.
|
|
show
|
1:57 |
What is an algorithm?
In terms of computer programs, it's really just the little parts of your program that have to make decisions or control the flow of what your application is doing.
Well, first we're going to check and see if a user is logged in.
If they're logged in, we're going to then get their courses and show them here.
If they're not, we're going to tell them, Hey you have to log in first, or redirect them over to a page that is the unauthenticated page.
Something like that might be how it works on the website.
Programs are not usually made up of the algorithm that makes up the program.
There's a bunch of little parts.
And each little part generally has its own algorithm.
Sometimes these are very formalized.
Sometimes they're just kind of thinking through to the decision-making.
So for example, if we want to get really formal we're not going to do that too often in this course but we could look at this.
This is Euclid's algorithm for finding the GCD great common divisor, of two numbers.
Take two inputs and you say, Is B zero?
No.
Is A greater than B?
No.
And then you have the steps and you go through it.
Most algorithms as we think about them in modern programming it's not generally this low level but sometimes.
Often, you'll find the building blocks that we use are built out of algorithms themselves and we can just use them.
We don't have to deal with the low-level details.
But that's what an algorithm is.
Sometimes this is almost used as a negative word in today's world.
It has algorithms have political bias or algorithms have racial bias or they have these other problems that are unfair or inaccurate.
And that's true but all that really is saying is programs sometimes, when people decide how they think or the data that they use, is imperfect and it has problems.
But an algorithm itself is just this neutral thing.
It's just kind of this decision-making process.
Take these things as inputs, do this sort of test carry on in this way or that way.
|
|
show
|
3:12 |
So, you've got this jar of M&M's and you come into a store and it's sitting on the counter there.
And they say, hey, if you can guess how many M&M's exactly are in this jar you're going to win a discount.
Or you'll have lunch for free, or something like that.
And, you're standing there, thinking well, I need a way to guess.
Maybe they're even willing to give you five guesses.
They'll tell you if it's too low or too high or something like that.
Give you a little bit of guidance 'cause you know, pure guess, that's a little bit hard.
Maybe they've been having the pure guess for two months and nobody's won.
They're like, fine let's try to give 'em some help.
So, you've got to figure out a way to solve that problem and that would be developing and algorithm that will address this situation.
So, you're the woman here on the right come in to the store.
There's the guy behind the counter and he says guess how many M&M's, I'll give you five tries.
If you get it right within five guesses then lunch is free, on the house.
She says, ah, okay, could you give me just a little hint, how many, max...like what is their upper bound, what is the maximum number of M&M's there could be?
He says sure, fair, a hundred.
Now, what does she do with that information?
The least zero, I can see there's more than zero.
Let's say there's zero to 100.
You could have a very naive way kind of like a child would.
Is there one?
No.
Is it two?
No.
Is it three?
No.
If you have this approach on average if the M&M's were evenly distributed through zero to a hundred you would guess, you would have to go through 50 attempts on average to get there.
Sometimes you'd get lucky and it'd only be 10 guesses other times it'd be 90.
It would be horrible, right?
People in line behind you'd be like hey, stop that number game.
Get out of here.
I want to eat my lunch.
Right and for you, of course you'd be very unlikely to get it within the five tries.
So there's other ways we could do it.
We could say, well, let's try to look at it half.
Like, right in the middle they're going to tell me if it's too high or too low.
Let me guess in the middle and that way the very first guess, I'll be able to exclude 50.
Right?
If I guess 50 and they say it's too high I know it's zero to 50 now.
If I guess then 25 out of that smaller one then it's going to be, when they say it's too low well then I know I've excluded the lower half.
And that's pretty much the most efficient way you can do it with no information.
So, she says is there 50?
He says, nah-nah, that's too low.
All right, half between 50 and a hundred, 75.
No no, that's too high.
So she says okay, well let me try to go to the half between those two numbers which would be 62 or 63, minus any broken ones which let's say there's not.
So it's a whole number, so 62.
Boom.
It was 62.
Lunch is on the house.
Now it might seem unreasonable that you went from 75 to 62 and got it but if you keep following this path eventually you're going to narrow in on exactly the answer every single time.
This is much more efficient than just going and saying is there one, is there two, is there three.
So this is a typical way to develop an algorithm, right?
Think about, well, what ways could I most efficiently solve this problem?
Because often in programming there's nearly an unbounded number of ways in which you could go about accomplishing something but there's usually a few better and efficient ways.
So cool, lunch is on the house.
|
|
show
|
2:03 |
We could have easily come up with this algorithm on our own but it turns out that many of these techniques appear over and over and they get applied to all sorts of different problems and these I will call formal algorithms.
For example, the thing that we just did is a Binary Search algorithm where you start with somewhere and then you start breaking it into halves and say, Can we exclude half of the data?
Yes, or can we, make sure we only focus on half of the data and start partitioning down.
And you can go learn all sorts of things about this given some amount of data in an unoptimistic case we'd have to make as many guesses as possible or until there is no other sort of path that doesn't allow for another guess.
It would be this complexity called O(log n) which means as you add more data 10 versus a hundred versus a thousand the time it takes to find the answer is the log of 10 or a hundred or a thousand as a ratio not exactly as a number.
And the best part is maybe you just guess the number straight up and that's just, doesn't matter how much data there is if you guessed right.
The point is not to look at this complexity and stuff but once you identify one of these formal algorithms all of a sudden you can see all the stuff that people have studied about it you can see, oh, it actually applies in this other case.
I first thought it was just about guessing the number of M&M's in that jar but it turns out it also helps me optimize this pathfinding algorithm or pathfinding program that I am trying to write.
I don't even know if that's actually true but once you know the algorithm you then know that it can be applied to all these different things.
So we're not going to go deep into a bunch of algorithms because this is not a Computer Science course but that's the idea.
You're going to run into these things you're like, Oh, I thought I just made this up.
But no, it's actually this sort of formal thing that was studied or somebody might tell you Oh, it's this kind of algorithm.
And then you can go and look it up see how to do it in Python usually there is a resource for that.
To these algorithms sometimes it's just thinking about how my users are logging into my site other times they're much more formalized like this search algorithm here.
|
|
show
|
7:06 |
No matter what your end goal is do you want to learn some programming so you can be better analyzing your data as a scientist?
Do you want to start a new startup like Google?
Or do you want to just manage some data while you're doing some accounting or automate simple things around the office or your even your house?
No matter what your end goal is you're going to go through different stages.
At first, you're going to be like wow, this Python, I don't really even know how to put it together correctly.
And you'll get better at the structure of writing Python code or source code in general you'll be able to do that reliably.
But when you approach a problem, it'll be like wow, I know how to do stuff in the language.
But this problem, I don't know how to apply the Python to this complex problem or how to break it down in a way that I can deal with.
So in this next short section I want to talk about the difference between pros and beginners.
In some ways, people who can just sit down and write whole web applications that are things like Google or, you know, do their startup.
You know, Mark Zuckerberg sitting in his dorm room creating Facebook, it seems like there's a huge divide between beginners and pros who are experts in that world.
But really, what you'll see is it's just a few bits of mindset, some practice and a whole bunch of persistence, really.
So let's talk about the differences.
Persistence to just keep trying.
Now, you might think this thing I'm trying to do is frustrating because I'm a beginner and I don't know what I'm doing.
That may be true, but a lot of times, it's just frustrating.
And that happens to experts as well.
I was working with a library just a few days ago and it was like, why is this thing not working?
And I've been programming for over 20 years and yet it is right there in front of me.
It's not clear what it's supposed to do.
It's definitely not doing what it's what I'm trying to ask it to do.
And how did I solve it?
I didn't use necessarily 20 years of experience.
I just kept looking for answers.
I just kept trying variations until the thing finally worked.
So do not discount, just persistence to get through these problems because it's not just that you run into them as beginners and they go away.
No, sometimes that's true for sure.
But it's not as true as you would think.
And along with that, just feeling like you're stuck on a problem, it's just part of the journey.
Again, as a beginner, if you feel stuck you might think, well, I'm stuck because I have no idea what I'm doing or worse you might think I'm stuck because this is not for me.
I'm not good at this.
No, like I just told you just a few days ago I was totally stuck and I've spent hours looking at this thing, trying to figure out why it won't work.
But difference as an expert is I know that that is part of the journey but it's also going to go away.
If I apply rule number one, I'm persistent and I just keep working on it.
But eventually, I'm going to find that article that somebody wrote or that Q&A that somebody did or that thing in the documentation I overlooked and it's going to unlock and then whoosh off it'll go again, you'll just be cruising along working, smooth, even keeled for a while until you hit another thing like this.
So being stuck is part of the journey.
And just because you feel that way it doesn't mean it's not for you it just means it's part of the journey.
Now one thing that does help is seeing a similar problem before on other projects that you've created, on articles, or in a book or something like that.
This does take a little bit of experience 'cause how are you going to see similar things when you're brand new?
Well, you just have to expose yourself to them and try solving problems and reading and taking online courses or even in person courses.
But going through and just getting that experience this is something that really is helpful.
Think I need to create a website and have users login.
Well, if I've done that five times before, guess what it's pretty straightforward to seeing how to solve that problem.
But if I've never done it, a research project.
The thing is, being really good at programming is not necessarily being super smart.
It's just going through a little problem after a little problem, after a little problem and having that in your toolbox.
Another thing that's super valuable are data structures and we haven't talked about these yet but organizing your data in just the right way makes it much easier to think about and it gels better with the language in ways that can process it and you can ask questions about it, and so on.
So we're not there yet, and when we get to the part where we're writing more complex code we'll get into the data structures and you'll see what I mean.
Much like the seeing a similar problem but more random fact based is having tonnes of very small and simple facts on hand.
How do I install this library?
Well, I know I typed this thing.
And if it gives me this error, like permission, denied I know, oh, I have to do this other thing in addition to that.
And just having all these little small facts on hand it really, really is helpful.
It might feel like it's something for the super smart this person just knows everything.
They say, do this little thing or that little thing.
But it's not smart, like physics and Einstein or large hadron collider smart where you've got this grand vision of the universe that people don't have.
You just have zillions of little tiny facts and techniques that you've somehow learned you've experienced, you've dug up and they just add up layer after layer after layer.
So again, the only way to get that is just keep working through it, be persistent.
Knowing the libraries, both the built in standard ones and the external ones you can use to solve a problem is super helpful.
There's places you can go look and we'll talk about that later when we get into the external library section.
But these complicated algorithms or things that you need to do understanding a complicated data file structure or some crazy thing like that you could either do tons of work that could be error prone frustrating and hard to solve that.
Or you could just go and grab an external library.
There's over 200,000 different libraries available to Python that you can say our this scientific data file, I if I need to pull data out of a telescope for astronomy there's a known format for much of those files and I can just go grab that library and say love that thing up.
I don't have to try to learn that but if you're new, you maybe don't know that.
You don't know that, Oh, I can just grab A library and write two lines of code instead of 300 complicated lines to try to figure out what this file is?
So knowing those things is really important and we're going to learn that in this course.
Googling for solutions and error details you'll hear people mock developers and often newer developers say Oh, they just copied and pasted that from Stack Overflow or they don't really know what they're doing they just Google for this.
That may be something that should be avoided, eventually.
We will see more as we go through this course.
But certainly, if you get stuck you're very unlikely to be the first person to have that problem and because it's Python there's so many people using it that it's very likely there's a discussion online about that problem.
Sure, sometimes you'll be stuck and you can't just go find the answer online.
But there's a surprising number for which you can.
Don't hesitate to Google the error details or more details about a library of what you're trying to accomplish.
It's actually pretty productive and that helps you see similar problems or acquire these simple facts that you just have on hand because you can level up through someone else's hard work of figuring it out.
|
|
show
|
1:06 |
If this conversation about beginners and experts and some of the techniques and even mindset stuff that you can think about that will help you if this sounds interesting, you want to go a little bit deeper, check out this podcast episode I did back for Talk Python, Episode 203.
This is back in March of 2019 and I had Ned Batchelder along with three or four self proclaimed beginners and we had this conversation, Ned being the expert me being the moderator, and then the beginners on there as well talking about their perception of problems and their path in the software industry some of then were software developers some of them were scientists, and it's really interesting to just be a fly on the wall and listen to those folks talk about their experiences.
Ned has great advice for coming an expert helping to speed that journey, if you will and definitely helping the beginners feel better about where they are and how much they actually do know.
So if this is interesting, I encourage you to come over here and listen to this episode when you got a little free time.
I think it'll help you out a lot.
|
|
|
37:25 |
|
show
|
2:21 |
The stage has been set and it is finally time to write some code.
We've talked getting Python set up so we can run code that we'd write on your machine.
We've talked about some of the big ideas behind programming force code what it means to execute source code algorithms and even, to a smaller degree, data structures.
So it's time to start writing code in Python.
Here's a little bit of Python code and we're going to write it in this little environment here.
What we're going to do, is we're going to start from the absolute simplest way that we can explore a few basic ideas in Python before we get into full-blown programs, and editors, and things like that.
We're going to use this thing called a REPL R-E-P-L it stands for, Read.
Evaluate.
Print.
Loop.
What you do is you type some Python expression in here it either gives you an answer or if there is no output that doesn't do anything and it just evaluates it it comes back and it loops around and it asks you again What do you want to do now?
What do you want to do now?
Real programs are not written this way.
However, it's the simplest thing that we can do to get started.
In this first chapter we're going to work in this Python REPL.
Afterwards, we're going to put it away because they are a lot of disadvantages here.
For example code that we type in here doesn't get saved.
If we make a mistake it's quite hard to edit what we've created in here and as long as we're doing complicated things anyway.
So real programmers they don't work here to create programs but they do work here to explore little ideas and that seems like a great place for us to start.
This is how it looks if you're on macOS.
Looks really similar if you're on Linux as well.
If you're on Windows, it looks a little bit different it's going to look like this.
We're going to go through and do a little bit of setup both on macOs and on Windows though either of those, you should be all set.
So don't worry we're using one and you're on the other we're going to talk about, real quickly how to get everything up and going get this REPL running the right version the right way and so on and then we're going to explore two core ideas in programming variables and reference types that's idea 1 the other one is data types themselves like numbers vs.
text vs.
dates that kind of stuff.
We're going to explore those and work with them in this Python REPL to get our feet wet and get started writing Python code.
|
|
show
|
2:04 |
Well, let's get our REPL running here on MacOS.
Again, if you're on Windows hold tight for just a moment and we'll get over there as well.
Now, I have to have pinned a terminal in my dock.
If you don't happen to have it pinned you can come over to your applications go to utilities.
Down here somewhere there's terminal.
And you can run that from there.
We're going to run it like so.
Now what's the most natural thing to do to get your Python REPL running?
Well, it's probably to type Python.
That sort of works.
This looks like what we saw before except for notice this is not good.
It's Python 2.
Now Python 2 is no longer supported.
There's Python 3 is the current version.
So definitely not something we want to run.
It just turns out that MacOS happens to have an old version of Python that has been shipping with it forever.
And because that's already there it's name is Python so we have to refer to it on MacOS and in Linux in a different way, we say Python3.
Remember, long as this is 3.6 and above.
So 3.6.whatever.
Ignore that six.
That's just not what we're talking about.
3.6 or higher you're going to be golden.
The latest version is 3.8.
But on this account I don't happen to have that set up that way.
Here we are in our Python REPL.
We should be able to do things like we saw on the screen Print, "Hello World!", make sure you put that in quotes.
And close in privacies.
Ta-da!
It's working!
"Hello World!" is often this little example shown say what is the least amount of code that I can write to get "Hello World!" on the screen in many programming languages?
Python it's incredibly simple, as you see.
Other languages it's actually a bunch of steps.
The real meaning and value behind "Hello World!" is to show you what is the smallest step you can do to get that on the screen.
It's to make sure that you can run the code in other languages, compile it and make sure that your system is set up to work.
So if you can get Python to run and you can type this.
And you get this to come out, everything's good.
You have the right version of Python and you're ready to go.
We'll start writing code in here in just a second.
But, remember, make sure that's 3.6 or higher.
|
|
show
|
1:51 |
Let's do our little hello world example.
In the command prompt in Windows I've already pinned this to my taskbar here so here's our command prompt.
But if you don't have it, of course you can just come over and type cmd and pick command prompt and then probably pin it on here.
So we're going to go over here and just like before we want to type Python.
However, this time when we type Python in Windows this, probably not certainly, probably means the latest one depending on how you installed it.
You installed it from the Windows Store you can also type Python3 and be sure to get the right one.
But there's many other ways to install it so you want to run probably Python.
Now here we have 381, that's pretty cool.
This means we're using one of the later versions and it looks like, most importantly, it's 3.6 or above.
If for some reason, you can exit out like this if for some reason now it said Python 2 you can type which Python or you can type over here Python which works in the other systems and it will show you all the places that it finds Python.exe.
First it found it in 3.8, and then it found it in 3.7.
Then it found it in the Windows Store version that we've installed.
Though, when you type Python it's going to run the very first one that it finds.
So in order to fix this in Windows if you have the wrong one, you have to make sure that you just set the path so that the highest version of Python, the one that you want to run, is first.
That's great.
Now we come over here and type Python and we have Python 3.8, that's great And we can do our print hello world.
Tada!
Everything works great.
Now another way to exit from this app here is we can type control z and hit enter and that just exit out.
That's the sort of a short-hand for typing this.
On macOS and Linux, you type control D.
On a Windows, control Z.
For whatever reason, those are different.
Doesn't really matter.
Whichever one you're using, you'll just get used to it to get out of there.
There we have hello world on Python on Windows.
|
|
show
|
5:36 |
Let's write a little bit of code play with some variables and even do a little calculation here in our Python REPL.
Remember we get started by typing Python3 on macOS and Linux, sometimes on Windows we'll figure that out when we get there.
We can get started by declaring a variable like we can say x = 7, y = 11.
And then you can do just standard math.
So the math operations, they're very much like, well what you will done in math class so x + y, we get 18, there's a prize there, right?
And if we want to work with that value of it being added up we need to have another variable like let's say z = x + y.
And then we can ask, what is the value of whoops that wasn't it, x + y.
And then we can say, what is the value z?
Again, it's 18.
But then you could do things like add one more to z.
Now what is z?
z is 19.
But then there is this little shortcut we can do a += to say take the value and increment by one.
It's like z = z + 1, you'll see that all the time.
So this is interesting.
We can do basic things with these variables here we have x, y, we have now z, we can add them together we can even say z / y and get some sort of floating point number that comes out of it like that.
Let's do something a little bit simpler and more fun maybe.
What we're going to do is we're going to clear the screen and on macOS, you hit command K, and clear that.
The other operating systems don't have that feature wish they did.
So what we're going to do is we're going to a creative name.
And I'll say my name is Michael.
Now we want this to be text.
And in programming language, in programming terms text always has to go into these quotes.
We have double quotes, you can use single quotes or double quotes, it doesn't make any difference in Python.
Some languages it does, Python, it doesn't matter.
You can just use whichever you like.
Often I actually use single quotes but sometimes double as well.
So we're going to create this variable and ask what it is.
Notice Python prefer single quotes when it refers back to us.
It says, here's a piece of text.
Now this type of data that we're working with when we have text is called a string.
That's different than say numbers.
So if we had like name, or we tried to add a number to it it'll say, oh, no, no, no you cannot put strings and numbers together.
It's really important that you have a basic sense of the type of data you're working with because certain operations are allowed to be done on data like again, with x / y, or z / y you kind of can divide name by a number.
We have a variable called name.
And we have a piece of data, Michael, which is text and that's a string or str in programming syntax.
Now, let's do something interesting with it.
Let's say my age, I'm going to be 42, right?
Let's put these pieces together.
We already saw that if we try to say name + age it gives us an error, that's okay.
We're going to make string, a piece of text out of those two pieces of data, those two variables though what we can do is we can create what's called an f-string.
So I'll say that there's going to be a message and normally an f-string is like this or like this.
But if you want to put other data into it like name and age, input just a little f at the beginning.
These are format strings strings that take data as part of what they do.
So we could say, Hi there, and we want to put the name we just put the name inside these curly braces.
So we say name, you are, age years old.
Like that.
Though if we say what is the message?
Hi there, Michael, you are 42 years old.
Cool, right?
So what we have is we have our string data which we stored into name, we have our integer data.
That's what type?
This is right?
Notice this int here, integer age 42.
And then we created a more interesting string using format a format, we said Hi there, whatever the value of name is you are, whatever the value of age is, years old.
So that's cool.
Let's go ahead and suppose I had a birthday, my age I could say equals age plus one, or again we could do that shortcut plus equals one.
And now, if we go and do our format again we just hit up arrow to go back and run it.
But if we recreate this message, we can ask what it is now.
Hi there Michael, you are 43 years old.
Cool, okay.
So we can actually ask what type of data we're working with.
It's very rare in Python that you would do this.
But as we're kind of exploring this idea you can use this operator called type so I could say what type is message what type is name, what type is age.
So you can see that it's a string, string and an integer.
It's not important that you know the exact types or often that you even say them some programming languages I'd have to declare this variable as a string before I get assigned string values to it.
I'd have to declare the age as an integer before I could assign integer values to it.
Python is way more loose than that it just lets you write values and work with them.
But as you can see, as we try to do these operations it does care about them.
And so having a little bit of a sense that there are these different types of data that store different types of information numbers as integers and string as text.
There's also different types of numbers like floating point numbers like 1.2.
Integers just represent home numbers and so on.
But having this little sense of a data type just is there in the background that you're working with tells you what you can do with the data the way you can combine it and so on.
|
|
show
|
1:33 |
Hope you enjoyed seeing a little bit of code written.
Now, we're going to come back and write a lot of code throughout the rest of this entire course.
In fact, now that we get farther into this we're going to spend most of our time writing code but we're coming up on a different type of presentation.
A very short one, but I want to make sure you understand what it's about and why it's here.
It's the concept section.
What we'll do throughout this course as we go through these demos and we do live codings we'll be playing around with ideas and we'll be writing code and doing a bunch of stuff.
And maybe that takes 10 minutes to get that whole section done.
Well somewhere in there is the key idea of that lecture and I'd make it possible for you to use this as reference material as much as learning material.
That's one of the shortcomings of many video courses so I've come up with this idea of the concept section.
What we're going to do is we're going to spend 30 seconds to maybe a minute on the core idea of what we've just learned.
That way, three months down the road when you're like I need to come back and just see how that one thing is done real quick instead of shuffling around through a bunch of demos and trying to watch and see what happened you can just jump right to this one video and watch it.
Alright, that's this idea of the concept section.
Some folk have been a little confused, they thought well why are we going over the same thing we just did that?
Well, that's why.
So, watch it, learn from it now but keep in mind that these are really here for reference material as well.
So if you need to turn back, you got that 30 seconds jump into a concept and you've reminded yourself of exactly what that was.
|
|
show
|
2:54 |
Let's review this idea of variables data values, and types.
We saw that we can create variables just by saying their name, and then giving them a value.
Though, in our Python REPL, Read, Eval, Print, Loop we were able to type x = 42.
Notice this green dip with a hash in Python you can make comments that are meant for people that have no effect on how code runs.
So we're going to say hash if we were to run Typhon X but what we'd get back is this class inch.
Remember we said there's a way in Python to ask What type of data are we working with?
And here when you work with whole numbers in Python that's an integer.
We came up with another variable, 19, also an integer then we saw we can use them in expressions like what is x + 7 * y?
Then if we don't assign it to a value that just kicks out whatever the response or the evaluation, the value of it is, so 175.
We can also create text base data and these are strings.
They go in single quotes, or double quotes.
Like we have here, so we said name = 'Michael'.
Now if we asked the type again this one has changed from int to str.
And you can combine strings and numbers by adding them together but if you try to mix these types it doesn't really like it so much.
Here we saw that there was an error if we said name + x.
We got an exception.
The program sort of crashed and if it was a real program that we were running it wouldn't continue, it would just stop and say Something's broken, we're done.
But in the REPL it just prints out the error and carries on.
If we didn't want to combine numbers and strings we can use a format string.
We know we have a format string because it has that little f at the beginning.
So here we say, Hi, pearly name.
And that just takes the value, currently Michael.
Looks like you did math, and then we want to restate the equation and then the value.
So x, {x + 7 * y} is going to be whatever that value is.
Now, I could've assigned that response or that evaluation to a variable.
We could've said something like z = x + 7 * Y and that's probably the best thing to do actually.
But I wanted to make the point that it's not just variables that can go into these format strings inside those curly braces.
More general Python expressions can go in there.
So, if you wanted to compute something or you wanted to call a function get some behavior out of a piece of data we'll see how to do that later.
You can do that there.
So, these are very very flexible.
And we run this code, we get Hey Michael looks like you did math, 42 + 7 * 19 is 175.
Aright, so here we've created a bunch of variables we've set their data and we've set their data values which implies a data type.
We saw that we don't say the type in Python but that it is important to know about it.
Like for example, name plus X, we should know that we can't do those things.
We need to do the thing at the bottom.
Create that cool little string that we got in the end.
|
|
show
|
5:41 |
In this next short section, couple sections actually we're going to visualize some of the code that we're working with.
Now you've seen it written, you've seen it executed.
And we've been able to ask questions like hey, what data type does it have?
But I want to make sure you have a really clear understanding of what these values and what these variables mean.
It turns out, getting a good grip on these things is actually one of the key steps and one of the cornerstones of becoming good at programming.
Though there's this cool bite here called Python Tutor over at Pythontutor.com.
Now, it's not entirely clear how you get started.
But what we want to do is we want to visualize our code or get live help.
We don't actually care about live help.
We're just going to write some Python code.
We could write other languages but we're just going to write Python code.
Now we're just going to work with one data type and all we want to see is how different variables and values interact.
So when we say something like person1 = 'Sarah' and let's have another person person2 = 'Michael' The things on the left, person1 and person2 these are just, think of them as names.
And those names can refer to data that exists out in memory values that exists with a type though the string Sarah and the string Michael or later maybe we write down the age it could be the integer of 42 or whatever it was we put in that section.
We can also take the values of variables one variable like person2 and assign it to something else.
So what if we want to express somehow that Sarah's friend is Michael we could rewrite Michael but it makes much more sense to take this variable and assign it because if this gets changed somewhere along the way you know, you want to be able to work with this much more dynamically, not just be super, super explicit.
So let's go ahead and just visualize what this looks like so far, then we'll make a few more changes.
Now in order to do that we're going to click visualize execution but to get the true picture we're going to pull down and say render all objects on the heap because hey, that's how Python actually works.
So let's click on visualize execution.
Now, look over here, it doesn't just take all the code and run it, what it's going to do is it says we're going to run one line at a time and then hit Next, Next, Next, if you want to run them all you can hit last, you could even move this little slider to zoom around through your code, okay?
What we're going to do is we're going to run this and we're going to take this variable you know, basically create a name and then we're going to create Sarah which is an object out in memory.
So here you'll see frames and objects.
Frames are basically the things that hold the variable definitions.
And then objects are the actual data with types out in memory.
Though let's hit next.
There's different kinds of frames don't worry about what this is just means it's not in a function or a class or something like that.
Now, we have our variable person1 and currently this variable refers to Sarah which is a string out in memory.
We're going to do the same for person2 hit Next, and we have another variable or another piece of data in memory called Michael and another variable called person2.
Now here's where it gets interesting.
When we say, the friend of Sarah is person2 instead of creating a copy of Michael, remember when we assign the value it says Well, what is person2 point at it points at this piece of data in memory right there.
Well, guess what, when you do this line four that just means a friend also points to, refers to has that thing as its data, as its object also called Michael.
Let's see a few other things we can do here.
Well, we could come up with a list we get a list of all people.
And don't worry about how we work with list yet we'll talk in depth about this.
But this list lets you hold on too many things at once.
And we could go to these people and we could say I want to put those two people, person1 in and I want to put person2 in.
Let's run that.
Oh, down there they are, now we're going to create this object this list, you can see an empty list out in memory that's what people points at.
And then when we assign it just like when we did this friend we're going to say, well, one of the things in this list is that piece of data called Sarah.
So notice now the list also points at Sarah and then it also points at Michael.
Pretty cool, right?
So we have our variables here.
And then this particular variable is a list a complex type, that itself knows about other pieces of data, and basically has pointers or variables in here that talk about hey, Sarah is my first piece of data and Michael is the second.
Let's do one final thing here.
Let's add a third person.
Mike or something like that.
Here, we can run this up to almost the same spot.
Now we have the same setup we've had those two pieces of data the two variables that directly pointed at them the friend who we said also now is a point there and then the list where we put them both in and also knows about them.
So now we just do one more step and say there's some other piece of data that's not related to this over here.
I hope this gives you a decent sense of what variables are and how they're different from the data or the values that they actually have, right.
So the variables are just names that at some moment and point out here, right, and that we saw before here, like the people pointed at the list but the list didn't happen to point at Sarah or Michael just yet.
Though here's a quick visualization of variables and their values as objects in Python.
|
|
show
|
3:48 |
Now we have this rough sense of what variables and objects look like.
There's one final connection to make.
We saw that we could create things like person one and set their name to Sara they're valued to Sara we could create person2 set their value to Michael then we change that well then it just changes what piece of data that variable, that name points to.
But not everything in Python is like that.
Many things are.
Many primitive basic types like numbers and strings and so on, they're like that.
But some of them are not.
Let's create a little example here and explore that.
If we're going to create a list again a list is just a collection of pieces of data that are in order don't worry to much about that we're going to talk a lot about list later just a simplest example we have to work with.
So we're going to come up with some numbers like these.
Let's go with other data it's currently going to be equal to VA data.
So what we're saying is we have two variables VA data and other data and they both happen to share point to the same object the same piece of data in memory.
Let's just look at that row quick.
So we can run the first line and whew that thing blew up what happened?
We have our list our list here and then we have this is our list, we're pointed out and then each one of this each part, each entry in the list actually points to something else in memory that is a value.
So it has a bunch of numbers these are all stored separately so we have a 1, a 2, a 3, a -1 and 20 and the 7.
That might not be the picture that you expected but it's pretty straight forward to go from here to there once you know that this is what happens.
What's going to happen when we go this next line?
Well, it's going to define another variable but it's also just going to point over here like this watch that.
Here we go, that's a pretty straight forward.
It's nice.
It means it's very fast but also has some interesting implications.
So let's go and check that out.
So this list has some really cool features.
What we can do is we can come to them.
Just do the first one.
We can say sort and if the things in the list has some sense of order like numbers or strings like which will be sorted alphabetically numbers in smallest to largest things like that we can just do this and it will automatically sort this data force.
Now let's run this and see and that small change makes a pretty big difference.
So, whew it blows up there's our first bit of data when it come along, we're going to define the other list or the other variable which also points at the same list remember you're going to see right here and there point at the same object.
Once that concept of them actually sharing the same thing in memory gets in your mind you can predict what's going to happen in line four.
Okay, because this can be confusing it's pretty straight forward here 'cause it's so close together there's only two lines but in real programs this relationship is not always obvious.
So what happens when we call the data that sort?
If we try to print out or otherwise look at other data let's actually go ahead and make it print that out in the end print other data there we go so when we call sort watch what happens.
Because they actually share the same object the same list in memory when we call sort on one the effect is to exactly calls sort on the other because, as you can see right here does same thing in memory.
So watch this when I call sort.
Boom, see the order changes.
Now that goes -1, 1, 2, 3, 7, 20.
Perfect ordering but if we print out this notice the output the value of other data is also sorted.
That's because when we do relationships like this they actually share the same piece of data and what we do in operation one obviously because there's only one of them certainly the same shared one it has effect on both of them.
|
|
show
|
4:10 |
Now before we ramp up this chapter let's write one more program in our Python REPL, and again it doesn't really make sense to call it a program but it kind of is.
We're going to cover two new concepts in this video here.
We're going to talk about using libraries.
Now, Python has an incredible amount of features built into it.
It has ways to get stuff off the internet to work with the calendars and the clock, and date/times and work with collections and do all sorts of interesting things.
You could even create a little web server out of the stuff that comes bundled in Python but it's not immediately available for you.
You have to ask for it as part of your program.
So, let's see how that goes.
We're going to start up our Python REPL again.
Remember, macOS and Linux, you type Python3 Windows 10, you might type Python3 if you got it from the Window's store otherwise you type Python.
So, here we are and what we want to do is we want to work with this library called sys.
Now sys comes with Python you don't have to do anything to get it.
Once you have Python, you have sys.
But if I type that, it says Whoa, we don't know what sys is.
So, let's fix that.
The way that you work with these libraries is you use the import keyword.
So we're going to say import we want to work with import sys.
If that doesn't crash, if that works then that means that sys was loaded.
You could ask for import some random set of characters and it would crash because there is no library called that, right?
But there is a library called sys so that worked and we loaded it.
Now if we ask what sys is It's a built-in module and sys has a bunch of cool stuff.
So we could say sys.versioninfo and here you can see it gives some kind of complicated response that seems to indicate there's a major version is 3, minor version is 7 micro version is 6, releaselevel is final and serial equals 0.
That should correspond pretty closely to 3.7.6 which is the version of Python that we have.
But now that we have this library loaded we can actually use it, all right?
This isn't going to be super interesting but we could come up with some kind of string or message where we want to print out a message that Python says, Hello instead of just, Hello, and welcome to Python it'll be, Hello, and welcome to Python version 3.7.6 on my machine, but maybe it would say 3.8.1 on yours.
It will say whatever the version of that, is.
So, remember we want a string which we go like this, there's our string and we want to format it, so we put the f.
Let's say, Hello from Python you can just say it like that and, Hey, hello from Python but we want is the version info in here.
Now remember, we need to say sys.versioninfo.major and then we say.
And this is not going to be pretty we're going to do a better version here.
sys.versioninfo.minor let's just say from Python 3.7 okay 'cause, it's gettin' long.
Hello from Python 3.7, well this is a lot to type and you might want to work with those numbers elsewhere and so on.
So, we could say ma equals the major version so sys.versioninfo like that.
We could check what ma is, it's 3 and then mi for minor.
Here we go, and that will let us I'm just using up arrow to get the history back.
That'll let us write something way nicer here.
So we can say, ma.mi like this.
Same thing, but this, I think is a little bit more clear.
You don't want to try to cram too much to have too much going on in there.
So, I kind of like to do it this way but you can do whatever works for you.
Here we go, Hello from Python 3.7.
If you'd written on your machine and you had a different version let's say you had 3.8.
This exact same code would say Hello from Python 3.8.
Pretty cool, huh?
Now remember, the reason that that works is because we're using this library.
It happens to be this library is built into Python and comes with it.
You can get others and add it to Python that's something awesome and we're going to do that and really take advantage of some cool stuff but for the moment, we're just sticking with the so called, Built-ins.
Let's see why they're called built-ins.
|
|
show
|
3:43 |
Last thing we want to look at is getting user input.
Now we were able to type name equals Michael.
And if this is our source code for our programming if this is what we write in our file, in our Python file it's always going to be Michael.
It doesn't matter what the person's real name actually is.
That's always going to say, Hello Michael.
If we write those two lines of code.
It would be nice if we could ask, Hey, what's your name?
And there's a very very simple way to do that in Python.
Though, because we're planning on typing here over and over it's not as obvious as if were running it separately but let's go ahead and do it here anyway.
So, the way you get the input from the user you ask them for input is well, you just use this input function.
And it takes a string value.
And a string value is the message want to prompt them with.
So we can say something like, What is your name?
Give it a little space here so they're not typing right on the question mark.
If we type this it's going to get the information from the user and then store it back into name.
Let's watch that.
What is your name?
Now I'm going to pick a different name.
My name is Jeff.
Okay, what happened?
Well, let's see what the value of name is.
Guess what?
It's Jeff and if we run this print thing Hello, Jeff.
Awesome.
Now this looks really good, right?
Let's ask what Jeff's age is.
Guess what?
Jeff is 42.
And that looks good.
Age 42.
Let's figure out what their next age is going to be like.
Next year you will be.
Let's call it next age.
It's going to be age plus one, right?
That makes a lot of sense.
Hmmm, you know, maybe not.
That was suppose to work.
That was supposed to be 43, but what happened?
Remember this type stuff we talked about?
Says you cannot concatenate strings, but not integers.
Or if you're trying to do math with integers you shouldn't involve strings in it.
Cause there's one final step we have to do here when we do this line.
Let's run this again.
Run it again.
And what we need to do is.
We need to convert, let's just go and run it.
42, we need to convert the age to say number or whatever is going to be take the string age and make it a number specifically I'm going to make it an integer.
So you just do that and you just pass age along.
So you say the integer parentheses, give it the age as a string and what comes out is number.
Now, if you say num verses age.
Notice one has quotes and one doesn't.
One is a number, one is a string.
Now if we want to do this trick we tried before.
But we make sure to use the converted number next age.
43.
We can give them a cool message like Great next year you'll be.
Now quick, this isn't going to work.
Why is it not going to work?
I forgot something.
Hmmm, that's not as cool as we want it.
Is it?
Let's give it a little exclamation mark.
It'll be super excited.
And remember, those evaluations in the curly braces only works for formatted strings.
So you got to put the F.
Great, next year you'll be 43!
All right, so that's how we got input from user.
We used the input function.
And then what we get back is always, always, always a string.
It doesn't matter if you ask them for a number and they type in number looking things.
Because it has quotes, you know it's a string.
Well, that didn't work.
So in order to convert to a number, we do integer of age.
You want to float like 7.2, you would say.
Well, Float or Float input numbers and so on.
There it is.
That's how we get it.
Input from users and convert it to a data type that means something we can work with.
|
|
show
|
3:44 |
It's your turn.
It's time to work on the practice exercises.
You've seen a little tiny bit of Python code and we're going to start writing more and more every chapter.
I'm going to dive deeper into it as we go but now that you've seen a little bit of code the really the best way to learn Python or any programming language, is to try it out yourself.
You just have to go through the motions you have to experiment with it and somehow working through it yourself just burns it into your brain unlike many other ways.
I mean, watching is good.
That gets you started but you've got to finalize it with doing practice.
So I've come up with some practice exercises for you, for this course.
Now, we're over here on the course page and the reason I'm here is we need to get to the Github Repository and the easiest way to do it is to just click this link right here.
So, here we are in the Github Repository if we scroll down a little bit here's the code that we have written or will have written.
We haven't actually finished very much code that we're saving yet we've just typed it into the REPL, but we haven't there's no files to save.
But the files we write are going to appear.
There's also these practice exercises so you can click here and practice or you can come down and click on practice exercises.
When we get here, it has the chapters of course you can just click on those or if you want, you can go through the little readme and click on Ch04.
And here we are at the practice exercises.
You don't need to download anything to get started you just follow along and it'll tell you what to do.
Hey, the amount of code or typing that you have to do is very, very minimal.
It's more about exploring the ideas.
It starts with an overview telling you about how practice exercises work.
Look, this is for you.
Do them.
I think they'll be beneficial to you but if you don't want to do them, skip it, it's fine.
Or if you get stuck for a really long time, you know don't let it kill you.
Just go to the next one, it's fine.
Now, before we get into the main exercises the things you actually have to do I'm going to give you some core concepts.
Now, we talked about the core concepts as a reference video but these are also the basic ideas of important things that we covered both during this chapter, but also that I think you're going to need to use for, you know, solving these exercises in this particular chapter.
So, it defines what the REPL is it talks about variables and values it reminds you how that goes it talks about what you have to do to use the built-in libraries with the import keyword how to get Input from Users, and how to convert text to integers and floating point values.
So you have those as your reference there you can read through that if you want.
Now, we finally at the bottom get to the exercises.
It's your turn, woo-hoo!
So here are five exercises that I'd like you to do for this chapter before you move on to the next.
At least attempt them, you don't have to complete them if you get stuck, but give it a shot.
So, try to run the Python REPL.
It might sound super easy, but if your system's not set up this is going to uncover that, right?
We're going to make sure you can run the Python REPL and you have the right version.
Talks about doing a little bit of math and working with variables getting some input from a user and then also converting that.
Hint-hint.
And, finally, here's one that we didn't cover it's kind of extra credit for you but there's a built-in library called datetime.
And if you write this line of code it will return a Date Time object which tells you the year, the date, the month the hour, minute, second of whatever it is right now.
So this final, more challenging version is to use those two pieces of information along with f-strings to print out what year it is right now.
To have the program discover the year and then tell you whatever year it is when you're doing it.
And, finally, pick one of these that you've done up here that you think is interesting and then visualize it over at www.Pythontutor.com This is the set of exercises I've put together for you.
Give them a shot, I think it'll help you get a solid foundation before we move on to the next topic.
|
|
|
33:41 |
|
show
|
1:00 |
It's time to write interactive code and this is where writing programs and doing software really fun.
So far, what we've done is we've just told the program Do Step One, and then Step Two, and then Step Three.
Maybe we got some input from the user but there was no decision or alternate paths made around it.
So, we're going to write code and make the code decide.
Think of the Talk Python website.
If you go there and you're not logged in it'll do one thing, if you are logged in, it'll do another.
For example, if you try to view a course and you're not logged in, it'll tell you to log in or it'll take you to the course to just browse it and you can learn more about it and sign up there.
Once you do log in, it needs to know does this course belong to you, are you registered for it or is this some other course?
And it's going to decide if you're registered, let's show them the lessons and let them get started on the videos.
But if they're not, well send them over to learn more about it so they can sign up things like that.
So this is where programs get real they get fun, they get interesting and they can do legitimately cool things and that's what we're going to do in this chapter.
|
|
show
|
1:10 |
Do you remember that jar of M&Ms at the restaurant?
Where we said there's going to be a contest if you guess the exact number of M&Ms in here and you win a free lunch.
And we had this algorithm.
Remember there was the person behind the bar behind the register there was the woman who walked in to order.
And the guy said Hey, how many M&Ms are in here?
You get five tries, if you get it right, lunch is free.
Free, all right, up around 100.
50, too low 75, too high, 62.
Boom, lunch is on the house.
There's a lot of decisions here, right?
When she said 50, the program had to decide is that too low?
Is that too high?
Or is that the right answer?
She said 75, same thing.
So we're going to recreate this little example but we're going to do it in code.
And that guy on the left, here he's going to be the program.
The person on the right she is going to be the user interacting with our program.
It's a pretty simple program to let us explore some of these ideas of writing conditional code that makes decisions based on the data that is provided.
And whether that comes from a user from a file system, from a clock, from the internet.
Who knows?
It doesn't matter where it comes from it's all the same principle and that's what we're going to build next.
|
|
show
|
2:48 |
It's time to write our first program.
We've written some Python code and we play around with it in the REPL but that doesn't really count.
What we want is something that we can save and run again on command and it just does whatever our program does.
We're going to do this using PyCharm Community Edition.
So I'm going to go and launch that here.
And PyCharm Community, is 100% free and it's available on macOS, Windows and Linux.
So you should be able to use this, no problem.
There's also a paid version but we don't need it for this course.
We want to going to go create a new project and then we're going to create our M&M game.
So we'll say, M&M.
Now it's suggesting that we create a new virtual environment.
And lets just let it go ahead and do that here.
This is all fine.
This is a way to create isolated environments.
So if we install other libraries they don't interact or conflict with other programs we might be working on.
Technically it's not needed but it's the default.
So I'm just going to go with it.
Later, we might use that.
We'll talk more about it near the end of the course but right now we're not going to use other libraries so it doesn't matter.
Right now, here we are and we don't have any way in seeing You see over here this is grayed out.
We don't have any way to run our program.
So lets go over here and create our first Python file.
So go over here and say, Right click, save new add on file.
And we can call it anything we want.
Lets just call it something like guessinggame, like this.
So over here we have our little game.
And lets just make sure everything's working.
Lets just do our little hello world trick.
Like this, we'll just print, Hello world.
And notice there's a little squiggly here.
PyCharm verifies that our code is meeting the Python standards.
There's certain rules about how we should write our code how we should name our variables and so on.
One of the rules is it should end in a new line, blank line.
If you hover over it, it says No new line, the end of file.
Then we'll just hit enter and that will go away.
So there's nothing wrong with the program.
It just happens to be PyCharm saying this is technically probably going to work but it doesn't quite follow the standards.
Now in order to run this and use this little button that looks like it should run something you have to right click on the file and say Run guessinggame or whatever you called it.
And then it runs down here at the bottom.
You can see, Hello world and any input or other stuff that's going to happen is always going to happen in PyCharm down here.
If you'd like to, you could always just copy this command here and run it in the terminal, if you like.
But for the most part just seeing the output happen down at the bottom is what we're going to need.
Alright.
Well, this is creating our project.
And yeah, it's not yet the M&M guessinggame but we're going to get there.
But this is the first step.
Make sure that we can use our editor and save this stuff.
This way we can make changes through our existing code and re-run it and see the changes here.
We don't have to like keeping typing it back into the REPL.
Woo, that's a good thing.
|
|
show
|
5:02 |
Well, Hello World was fun but it gets old pretty quick and it's not what we're trying to do, is it?
We wanted to create this guessing game.
So, there's a couple of things that we need to do at the beginning; maybe it's worthwhile to do a little printout thing, here.
Let's go ahead and put a little bit of a header thing like a message that comes out of the top to say Hey people, you're playing this game!
Now, you're going to see me do a couple of commands when I'm in PyCharm; certain things that'll just happen on the screen because there's a keyboard shortcut but there's not really a reasonable menu item to do.
So, watch this: I want to have this line I want to have one above and one below and then put some stuff in the middle.
I can type it again, I can copy and paste it but in PyCharm if you just hit Command + D or Ctrl + D on Windows, it will duplicate it but notice down here this duplicate line thing.
If I do it one more time, it even has the Command I pressed and then the Windows and Linux commands as well.
So, this thing I've added to PyCharm doesn't come built in with it it's called Presentation Assistant and it'll show you the keys so if you see something happen on the screen you'll be like, Oh wait how did that happen or what command was that?
Just look down below and you'll see it.
This also works for the menu items like here we know we can press this but if we press it, you can see run this, would be Ctrl + R.
If I wanted to use the hot key or Shift + F10 or sometimes F5, depending on how you set up windows.
We have this Presentation Assistant set up and that's pretty cool.
Let's do one more thing here.
We want to have some kind of message like M&M Guessing Game, alright?
Something like that is going to print out when we run it and we'll see it on here, it's our little M&M guessing game.
So we're going to take a lot of small step as we do this here.
Let's do the first thing, as we want to figure out how many M&M's are in the jar.
One thing to do would be, something like this.
I guess we said it's between zero and 100, so lets put 78.
Okay there's 78 there.
Well, this game's fun once, right?
But as soon as you've played it once then it's like, Well, I guess that's the end of that.
So, we don't know.
But let's go ahead and have it randomly generate this let's have the computer come up with how many M&M's are in there and then we'll play the game based on that number.
Now remember, Python has many, many built in libraries and features, and one of them is around this random library.
And the way we use built in libraries or other libraries is we say, import and then we say the library name.
And something awesome about PyCharm is it knows all of these things.
It knows what libraries there are it knows what functions that can be done what operations can be done on various pieces of data and so on.
If I type r, notice it has random re for regular expression, readline runpy, calendar, all sorts of stuff.
But we only have to know if it has something to do like random, so type that and then, boom.
We get the answer.
So that's cool, and then down here we can come down and use our random library, so if I type ra, you can see again that's right here, then we hit dot, we have random we have choice, but the one we want is randint.
Now we're going to come down here this is what's called a function, so we execute it with these little parentheses, like so.
Just like we were with print.
And then you can see over here if I hit Command + P or Ctrl + P on Windows it'll tell me the things that have to pass, a and b.
Well, that's super not helpful.
I guess it takes two things, what are they?
I don't know.
But we can come over here and I say view quick documentation.
And it says, this returns a random integer, n such that n is between a and b, inclusive.
Oh, okay.
So, I guess what we want is one to 100, if it's inclusive.
Here we go, so let's just print out what we got.
This is obviously going to ruin the game but just to see that it's working we're going to take this back out soon as we verify everything's okay.
So I learned from Presentation Assistant that instead of going up here with a mouse I can just hit Ctrl + R, I will.
Mmmm, guessing game.
So 16, 16 is the number of M&M's in the jar at the moment let's run it again.
24.
74.
76.
52.
92.
81.
32 and so on.
Apparently, yeah, this random is giving us a number between one and 100 as a whole number.
So that should work for getting us started.
Now, we'll be able to use this in the rest of our program.
We're going to ask the patron that comes into the store Hey, how many M&M's are in the jar?
And then we're going to compare it against this.
We won't show them that until they win or they give up.
Remember, they get five chances.
And then if they win, or they run out of time we can tell them, Actually there were 76 M&M's in the jar.
So very cool, very easy to come up with this random number.
We don't have to ask somebody Hey, go to the side and enter the number of M&M's.
Or hard code it so that it's always the same number and the game's only fun once.
Where we imported our random and we created a variable called M&M_count.
This is typcially how you name variables in Python it's all lowercase and then if they're compound words like M&M count, then you'll separate that with an underscore.
If I'd named it different I'd bet that PyCharm would complain?
No, not yet, but there are some tools that'll complain that you've misnamed things.
Alright, so we've used our random int.
Which comes with the random library.
We come up with this number we're ready to start asking the question How many M&M's are in the jar?
|
|
show
|
6:03 |
Now it's time to get the guess from the user at least the first guess.
Before we do though I want to show you something really quick over here in the GitHub repository I've already checked in, you can see in this section here I've already checked in the work that we've done to do this, so far.
And with GitHub and source control you can see the different versions, over time through the history of these various files.
You can look at what they look like, and so on.
So I'm going to be saving our code as we go through this so you'll be able to jump around in time, basically.
Alright, back to our game.
Now, we could do basically two ways here.
There's a couple of options.
The pieces we have to work with will only allow us to write kind of a crummy version of this but let's just get started and then we'll I'll teach you one more concept that will make this much, much, more nicer.
So let's come down here and say the the guess it's going to be the guess that the user makes.
So this will actually be the first guess and we're going to ask them again.
Let's do our little print message.
But do this little print.
And then if you just do print blank that's going to just be a blank line.
And then over here we're going to show them a message, say how many M&Ms are in the jar?
Remember, the way we do that is with input.
So we'll say...
Put a little space so when they type it doesn't look like they're typing without proper spacing.
Now, we would like to compare this against the M&M count.
But remember, the problem...
this is not a number.
It's not an integer.
It's a string.
And you can't compare, well you could compare them but they'll never be the same.
For example, if you said...
is this and this...
Are they the same?
They're never the same because they're not even the same data type as far as Python is concerned.
It could be confusing at first but that's the way it works.
These programs are very, very, specific and when you compare things one of the beginning requirements for them to be equal is that they have to be the same type.
So we'll come over here, and remember the way we convert this, is we say guess_text and I can even type GT, and notice the two blue letters in PyCharm...
it's saying allright?
We're going to just select that for you and give me everything that it knows about that has a G and a T, with some sort of separation.
So we're going to do this...
and then we could print out just the guess real quick as a number.
Let's just see that work so far.
How many M&Ms are in the jar?
17?
Yes.
17 M&Ms are in the jar.
But we don't know.
Maybe.
Maybe not.
But this is their guess, we've got their guess correctly.
So what's the problem here?
I told you this is a little bit simplistic and it's not quite going to work.
Well, the problem is, if they get it right, great.
They've won.
But if they get it wrong, remember they have five guesses.
They have five guesses, and so we have to ask this again.
So do we then do this again, and this again, and this again?
Well, that looks horrible and, no, we're not going to do that again.
So we're going to do something different.
What we're going to do is do something called a loop.
And there's two type of loop in Python Loops.
One of them allows us to go through a collection of data.
Remember we saw those numbers like this?
If we had some kind of collection of data like 1, 1, -2, and 7 is a really nice way to go.
I just want to go process them one after another.
Let me look at one, and then one again and then -2, then 57.
That's very, very, common but in this case that's not what we're doing and we want to continue to do something as long as some case is true.
The cases, either they've won, or that they they've only tried more than the times they can get.
So I'll say tempt limit, or something like that gong to be 5.
And attempts is going to be 0.
Alright, so we need to keep track of how many times they've tried this.
And then what we're going to do is we can write this loop so we'll say while attempts < attempt_limit.
Then we're going to let them do it.
Now when we define things like loops or we'll see if statements and conditionals what you have to do is you have to tell the program, Python what part of what...
what constitutes the loop?
What is the thing that you're doing over and over and then what happens after the loop is done?
So notice I typed a colon here.
That tells me that this is the beginning of the loop.
If I hit Enter, notice how PyCharm indents like that indented four spaces.
It automatically does that for us.
And that's because PyCharm knows in order to be in the loop you have to indent.
So we're going to do...
actually this one we want up here way up higher before we do any of this stuff.
This is the stuff we want in our loop here.
So what we're going to do is we want to indent that four spaces which we can do with just a tab.
If you want to do more than one line you have to highlight them all and hit Tab.
Then it indents it.
So the way this little loop thing is going to work is it's going to do this, as long as it's true.
Well, how long is that going to be true?
Conceptually, you might read it and you think well 5 times.
No, no, no.
It's going to do it infinitely many times.
Why is that?
Well, it's because this is always 0 and this is always fine.
And 0 is always less than 5.
What we need to do is, we need to make sure that...
Let's go ahead and print our guess in here, as well...
That every time through, we're telling it Well, you've made an attempt.
So we're going to go from 0 to 1, 1 to 2, 2 to 3, and so on.
That's how we do it.
That's just out here...
I'll just print.
Just to show that this loop is working.
Let's just run it.
We're not checking to see if you win or anything like that.
So let's say 723..4...9.
We get one more attempt.
Boom.
Cool, huh?
All right so it's much better than writing code more than one time.
Because often you don't know how many times.
Either we want to do this as many times as they're allowed but if they get it right the first time we're not going to ask them again.
That would be weird.
So we're just going to exit out of the loop early.
I'll show you how we can do that, as well.
Here's how we're going to get input from the user as many times as we need.
|
|
show
|
3:55 |
We're getting the input, the guesses from the user but, we're not comparing them against the actual M&M count.
So, instead of just printing out which is just silly let's do that.
So what we're going to do, is we're going to do another type of decision making in code.
This actually is a way of doing as well either you go in the loop or you go in the loop a bunch of times or you might not even go in this loop.
But the most fundamental piece that we're going to work with is this idea of an if statement.
So we'll say if and then we put some kind of test.
Very much like this, we'll come down here.
And we're going to say is the M&M count equal to a guess.
Now, in programming, this equal means take the value of guess and assign it to be the value of M&M count.
So, in these tests we have equal equal.
And then, just like all the other blocks of code that we talked about, like with...
Wow, we're going to put a colon.
And then we're going to do something cool, here.
We're going to say you win or something like that.
Let's say print out, you got free lunch.
It was, and let's put out the number, here.
And remember, that's an f-string.
We could use guess, we could use M&M count doesn't matter, they're the same.
We could come down here and say else, but remember we're going to give them some kind of guidance if it's too low or too high.
So, we don't want to just say, nope!
Try again.
So we're going to say else if, and then Python.
That's shortened to.
And we want to say, M&M count.
Oops, M&M count.
Is less than guess, so it it's too low we'll print...
Sorry, that's too low.
And then again, if it's not equal and it's not too low, then, it's going to be too high so we can just say, finally fall through this other case.
That's too high, like this.
And let's make low and high super obvious.
And we'll just do it like this for now so they can just quickly see, yep, low high.
All right, well, that's great but when they win we don't want to ask them again.
Right now, we're going to go through.
Let's go ahead and just run this and see what happens.
How many M&M's are in the jar?
I'm going to use my binary search algorithm we talked about, 50 and that's too low, okay, 75.
Too low.
85, too low.
90.
95, woo!
Ah, too low.
Try again.
It's not that many guesses, is it?
50!
75.
85.
100.
looks like we have some kind of problem here.
What is going on, if it's the same?
Ooh, whoops, I tricked myself there.
I should probably think of it like this way.
Guess is less then M&M count.
So we were saying when it was too high actually that's too low.
And that was obviously drive me to do it the other way.
So let's do it like this.
So, if the guess is less then it's too low otherwise it's too high.
Now, let's do our binary search.
50, that's too low.
75, too high.
Ooh, that looks like it's working.
65, 60.
Alright, we know it's between 50 and 60.
Alright, yeah, so let's see, it's going to be 54.
Not good odds, but yes!
Nailed it, look at that.
I got it.
I had 1 in 10 odds and I still guessed it.
So, you saw how the binary search algorithm narrowed it down but remember, this is a contest.
You win a free lunch, it's not just going to let you ask forever.
So yeah, we got pretty lucky there and got our free lunch.
So, that's cool.
Now, it's a little bit, uh...
Let's just do 1, a little hack here Comment this out with a hash and just put that as 7.
Cause I want to know what this is cause I want to show you what's wrong, watch if I guess 10, that's too high, and if I say 5 too low, and I say 7 yes, free lunch was 7!
Now it's asking, hmm...
How many are there?
7.
Again, it's still 7.
All right, I got 3 free lunches or something.
So, we got a little more work to do.
But, we did get our test here to actually check did you win?
is it low?
Is it too high?
That's working.
|
|
show
|
2:24 |
Let's put my little hack back.
So we know exactly when we're going to win.
We've got our back and forth with the user already working and that's super cool.
The program is taking the data and then it's like having basically a conversation with the user.
That's super cool.
But what's not cool is when I come down here and take a guess and then I get it right it won't just say, cool, here's a menu, go order.
It keeps asking us exactly five times.
So, there's couple of things we can do here.
One, you look at what's happening so far we could take this and we could kind of use this in like, not the way it's meant to be.
We could say that's equal to the attempt of limit.
There, like so.
Now, by the way notice there's a little two spaces I got accidentally here and this says there should be a space.
Maybe there's a bunch of lines and I wanted to clean up this code PyCharm has this cool thing where you can go code, and say, reformat code Command + Alt + L, or you can just hit, Command + Alt + L and it'll clean up the code.
So you'll see me reformat code all the time to make it nicer.
Okay so we could do this and technically this will work.
I'll say 10 oh, not like that.
I'll say 10 and then I'll say 7 wooh, you're out.
But there's just something a little bit ick about this.
What if down here, we want to say something like you're done in however many attempts, right?
We want to print that out.
Well, if we come down here and get it and you're done in 6.
No I wasn't, I was done in one!
So, there's just some kind of weirdness like we're kind of abusing what this is for and the reason I bring this up is Python has a special keyword let's say, I don't care what you're doing in the loop I don't care what this test is just stop.
Just leave the loop and just go.
We're done.
We're done with the loop right now.
And it's super easy you just say, break.
And then you say, break and this just means you come down here and then as soon as you get to that you just, you don't ever do anything with the loop again you just exit out and you just pick up right on line 27 which just says this.
So let's test that one more time.
10, no wasn't 10.
If I take seven, this should do it, and it should exit out.
Boom.
Got it.
And you're done in some number of attempts.
It looks like we've got a small ordering issue if we're going to print out the number of attempts.
So let's put that right up there one more time.
There we go.
You're done in two attempts.
Perfect.
This is working.
|
|
show
|
3:50 |
So you saw over here that we hard coded the count of the M&Ms so then I could play around with going through it knowing what was happening.
But we can actually do better than that.
Sometimes it's impossible to hard code stuff because you don't control it.
Maybe you need it from somewhere else or something like that.
So what we can do in PyCharm and other editors like Visual Studio Code is we can use something called a debugger and debuggers are super, super cool.
They're incredibly valuable for helping you understand what's happening as your Python code or source code runs.
So what I can do is I can scroll over here in between the number and between these texts here I can click and it puts a red break point its what it's called and a whole like's kind of followed here.
So if I just run out like this nothing happened it just run like it did before and so on.
But there's another button that kind of looks like a bug for debugging this let's go back up here.
If I run this it can have a little bit different look down here and it's going to stop right on this line right with that break point is you can see it's stuck down here on you know guessing game you see it stop down here on line 10 just like it says right there.
So if I step over if I go one line forward using this see this step over this means just go down this file one at a time as opposed to go try to go inside this library and see what it's doing which would be this one and click this and now, see that little gray piece up here M&M count is 26 and then down here M&M count is 26.
I can even go over here and change the value to something other than 26 if I wanted but let's go along a little further.
Oops I must've hit the wrong button.
So now the count is 79 so when we go down here and notice we've gone our, while attempts are like we say I'm going to step notice attempt limit is 5 current attempt is this we step one bit and then we going to go over here and notice the console is asking for input we actually know the answer is 79 but I'm going to just say it's 70 and notice here's the guest text coming in and then we're going to go and convert that to a guest number now 70 without the quote and I'm going to increment the attempt notice it goes orange appear that means it's value is recently changed so it's orange because we change it right there.
Now we can compare M&M Ncount 79 against guest 70 and let's see what happens says no that's not true so to the next test sorry the guest is too low that will come out here.
Now we're going to do another test one is still less than the limit so let's keep going we go back to the debugger and see the values.
When it's asking for the user input it's like hides all its values so let's put 80 and now it comes back and will show its value again we can see out attempt is 2 our guest is 80 and let's just keep going that's too high.
Let this time get it right and over here.
79.
Alright, 79 and let's convert that to 79 right there.
One more attempt, it's going to go from notice up here from 2 and it's going to shown orange it go to three now it's going to be right so perfect.
We're going to say you got this free lunch and then break should take us down the line 26 empty search prior go to 27.
Boom, there it is.
We were done in three attempts.
Stop, that's the end of the program.
That is super, super viable if you're having problems with your code working right you're doing a test and it's not quite doing what you're expecting or even you're getting the error.
So this debugger is extremely easy.
Click here, click there and you're going in PyCharm and yet it's really, really powerful to help you understand how you're code is executing and what the values are at any moment.
|
|
show
|
0:52 |
That program we wrote, that was pretty involved.
Yeah we only used a few core concepts but they were really important things that we covered and we kind of built this little kind of game challenge type thing for our customers that was cool.
When we want to have some kind of conditional logic branching logic, do this or that based on some condition we used the if the, elif, and the else keywords.
So in this case we're going to get a number some random number and a guess from the user.
You can imagine how that goes from the previous example we just did and we're going to test, is the guess too low.
If it is, we're going to print out a message hey the guess is too low.
If the guess is too high, we're going to say else, if, elif is the other test, is the guess too high then it's too high.
If it's not too low, it's not too high it must be Goldilocks, it's just right so they must be equal.
We're going to say yes you got it.
There were however many numbers of M&Ms in the jar.
|
|
show
|
1:40 |
We saw the values that go into the if statement or elif statement or even the While statement have to evaluate to True or False.
So let's talk about this idea of truthyness.
That maybe sounds like a weird word that doesn't quite make sense but the idea is that different types of data can say for certain values I want you as far as the execution goes as far as the conditional blocks to go we treat this is True and this is False.
So for example if you have just have the word False well then obviously that's False that is what the definition of False is in the programming language.
But if you have a list and it has no data in it well then that's considered False but if it has like one, one, and seven.
It has some data in it then it's True.
if you have something called a dictionary or a set those are the same kind of rules.
if you have a string well empty strings are False but non empty strings like "Hello" that's a True statement.
So this is a little bit of a weird idea at first the idea is instead of trying to come up with some kind of test like is the length of the number of items in the list equal to 0, yes or no?
You can just say if the list so it simplifies these tests.
Also for numbers if there's 0 that's False otherwise they're True and then none is a way to say this variable has no value at the moment.
That's also False.
if it's not one of these things in the list then it's True.
So we'll see an example of this in just a second but this is leveraged all over Python if you've got numbers you've got collections you've got strings, very often the way you test whether they're empty or not or their have decent values in them or not is to just do if the variable, carry on.
|
|
show
|
1:38 |
We've seen if statements and we've seen wild loops, and we've also seen truthiness.
But, what if you have two different conditions you have to test at the same time?
So imagine you're writing a website and it's an e-commerce site.
People have a shopping cart they can put stuff in the shopping cart, and then later somewhere you can tell them hey so and so, you have this many items in your cart.
Well there's a problem you can really only have a shopping cart if the user is logged in.
Because if they're not logged in where do you put their cart info?
So we want to check both, that the user is logged in and that they have items in their account.
So if they don't have either of those then we are going to do some else statements.
So we'll say you have some number of items in your cart so and so, Michael Thor, log in and add some items to your cart.
So we're going to get the user account which is a number, and we are going to get the user which is an object.
It can either point at something or it could be none.
Those are the two basic values you can have here.
So we're going to test both of them.
One, item count greater than zero.
If we were sure it wouldn't be less than zero for some weird reason.
We could just say item count with that truthiness table but lets be a little bit explicit here.
Then we also want to check that the user is not missing.
So we can just say user and then we combine these with various words the yellow here.
We say and this means we want to check both, that they have items in the shopping cart and they're logged in.
If it was sufficient that either of these were true then we could say item count or user right?
It might just say you have zero items in your cart Michael, if your cart is empty, but you're logged in.
Alright so you can use and, and or to combine these various tests into more complicated ones like this.
|
|
show
|
3:19 |
It's time for some practice exercises.
So again, the easiest way to get to the GitHub Repository just go to the course page and click right there.
We're going to go down to our practices and now we're in chapter five, interactive code.
So let's see what I've put on deck for you here.
The idea is work on these, but don't let them drag you down.
Don't get stuck.
Don't stop going to the class and for some reason, you do get stuck there we talked about how to get help at the beginning of the course.
All of those things but eventually move on if you get stuck but here's the idea.
I'm going to cover a couple of core concepts how do you run Python code, not in the REPL but execute a Python source file so we talked about that and it's up there if else statements, here's some examples for those also while loops, you're going to need both of those in the exercises.
Something we haven't spoken about but is really interesting and common in programming is actually working with the remainder.
Turns out this is more useful in programming than it is in, like, regular life so we all know about remainders like if you do whole number divisions say like 19 divided by 5 well that's like, 3.8 but in whole number division it's three with four left over, right so there's a way in programming in Python to say, give me the remainder of this division so 19 %, modulus, mod, 5 with the remainder which is four.
The reason we need this is, in the exercises I ask you to work with even numbers, and this is how you check if something is even, right there.
Now you have those as reference to work from what are the exercises?
First one, here we go again, hello world.
Idea is just to create helloworld.py a file that prints out hello world like we did before but now just make sure that you can execute a Python file right, so there's some examples above if you do this in PyCharm that's easy there's some notes here on how to do that.
You're not using PyCharm there's also some notes above on how to run it.
Next, write a program that requests a number from a user and then print out whether or not it's even or odd.
So, that's simple, and then you can extend that program in the next exercise, here to continue to ask that question as long as they provide a non-zero number.
So if they provide 27, say odd if they provide 90, say even but if they provide zero, say goodbye and stop the program exit the program nicely.
Right, so that's the idea and then pick one of these ideas over here and visualize it at http://www.Pythontutor.com.
Alright, well that's the exercises for you be sure to practice them, also if you'd like go ahead and go through the example we did in the videos remember the example that we did is up here we go back into code, here Vector five, that's the M&M game without going exactly through this source code here why don't you go and try to recreate this little M&M game or some variation on it for yourself using just the stuff that we saw back here with some of these core concepts and what not.
That's one more thing to throw in there for you to practice and hopefully you get good at if statements, while loops and making code decide things.
|
|
|
55:31 |
|
show
|
2:40 |
So far, we've written the most obvious and straightforward code that we can.
And it's worked okay.
Our little guess the number of M&M's in the jar project that worked pretty well.
But our code was lacking some really important things.
And that's organization.
You'll find out that the simplest way to write code is not always the best for the long-term.
And Python has four major areas or ways to organize code.
We have the ability to put it into multiple files and group the stuff you put into individual files by the functionality or logic that all goes together there.
We have what are called packages.
These are things we can install off the internet or share so it's kind of like multiple files but more so.
And we have something called classes for object-oriented programming.
It's a bit of a more advanced topic.
We're going to save that for another course.
But the most common and most important way to group Python functionality and to make code reusable is to use something called a function.
Now you've seen function used a ton.
When we created that random number remember we had to randomly determine the number of M&M's?
Well, we went and imported the random library and we called a function called randint And it took a lower bound and upper bound.
It turns out that we can create these in our own program and they serve two really useful and important purposes.
First, they let us think at a much higher level.
Instead of thinking about all the little tiny steps we can gather that up and group it in a function and then we can just think about the core idea or the thing that that function does.
For example, in that random int function there's probably tons of complicated stuff going on but we don't have to think or care about that.
We just know there's a random library and we can call randint and it'll give us this random number between A and B that we pass in there.
And that lets us think in just that level not all the details about how you actually create random numbers properly and so on.
So that's one important thing we're going to focus on gathering the code up and just kind of giving it a name and only thinking about its general behavior.
The other is reusability.
Remember when we created that loop so that we didn't have to ask the user 5 times and just copy that code 5 times, but instead we put it in a loop, then we could do cool things like test, have they exceeded the number of attempts or if they already won, let's stop going through the loop.
That was kind of what we can do with functions but functions are way more powerful.
So we'll be able to gather up some functionality and the function will take data that goes in and it will return data that goes out and we can pass different bits of data at different times and reuse that functionality.
So in this chapter, we're going to focus on functions looping our codes so that we can think more clearly and high-level about it.
And then reusing that code through functions as well.
|
|
show
|
2:16 |
It's time for a game and in this chapter as well as in the next couple of chapters, we're going to focus on a game you probably already know.
Rock, paper, scissors.
Here's a little graphic from wikipedia that talks about it so, you have a hand symbol, the two fingers up mean scissor the flat hand means paper and the fist means rock.
And they have this relationship that paper beats rock rock beats scissors, scissors beats paper and of course you can tie.
Or you can pick one where one of the players wins.
So we're going to build this game and we're going to actually build it over the next couple of chapters layer by layer.
Starting out really simple and then we're going to convert to reusable more clean code with functions.
Then we're going to apply really interesting data structures to make it way more useful and generalized as well as simpler and we're going to have it read and write files so that it has things like leaderboards and other config extensibility things.
So users can create their own types of rock, paper, scissor games and so on.
It's going to be really, really fun.
But this is more than just a game.
Maybe you're familiar with karate kid, here we have Daniel and Mr.
Miyagi and Daniel's learning to become a karate black belt or something, I'm not sure if he even gets a belt.
But He's studying for Mr.
Miyagi and he wants to learn karate and fighting and all Mr.
Miyagi asks him to do is, wax his car.
Wax, on, wax off if you remember that.
So he does it over and over and it seems like what are we doing, isn't this like, this is not what I want to be studying.
I want to be doing a real thing I want to be doing amazing stuff, I want to be fighting or defending myself or whatever his goals were in that movie.
And here he is just waxing a car.
It turns out much like the practice he got doing wax on, wax off of the car, it taught him sort of muscle memory of some of the karate moves.
Building this game is actually going to dive into many, many really important programming concepts.
Now what you'll learn from this game, well it is a game will let you build software for banks, websites all sorts of stuff.
Obviously there's extra details you need to learn for those other systems but this is a really good foundation that we're going to get out of this rock, paper, scissor game.
So I hope, hopefully you're excited learn it and build it and play it because it's going to be allot of fun and I think you'll be surprised what we come up with in the end.
|
|
show
|
6:17 |
Well, with our rock paper scissors we're going to start from the beginning.
So let's open up PyCharm Community Edition here.
And here's our old M&M game, but we want to create a new one.
Now, we're going to create our project over in Ch06 Organizing Code with Functions, in our GitHub repo and we're going to call the overall folder rock's game.
It's not actually really going to come into play so you can call it whatever you want.
We're going to let PyCharm create a new virtual environment based on Python 3.7.
Virtual environment is not really required but it's good practice to have it for later.
Right, here we are and we have no files yet there in our virtual environment, which is ignored.
So let's come over here and create a new Python file call it, hold on, rpsgame, our game like that.
Now, here's our game.
Remember to start running it.
We're going to right-click here once and then Run and then now we can click here.
Use Control + R, there's all sorts of ways.
It does nothing but exit with code zero.
That's a good sign.
That means that Run it just doesn't actually do anything yet.
So what we need to do is we're going to write this in a simple form like we did with our M&M experiment and then we're going to organize it and make code reusable and simple more simple, and whatnot, using functions.
So let's just put a little header here something like this.
And then in between, we'll put rock paper scissors v1, be our first one, put that right at the top.
Now, in order for us to play the game we need to know what the rolls are.
We also need to know what the players are.
So let's say player, player_1 in the input, enter player_1's name, like so and then we'll do that for player_2.
That's going to get us our two players.
And then we also need to know what rolls are available.
Now, we could have, these are separate variables but it turns out it's much easier to work with it if we have some way to say this data structure or this variable, it holds all of the potential ways in which you can play the game.
You play a rock, could you play scissors?
Yes, but no, you can't play sponge or whatever.
So we're going to have this thing called rolls.
This is going to be one of these lists that we've used before we haven't talked a ton about.
So we put square brackets.
This is going to create a list multiple things we can put in there and then we just put multiple strings separated by commas.
The first one is going to be rock, paper and you know what the last one is?
Yes, scissors.
Well, let's just see how we're doing.
One of the things I like to do when I'm working on programs especially when something is new to me is take baby steps.
We don't want to try to write the whole thing or worry about the whole thing.
Let's make sure that this part works.
So let's print out the rolls that we have and let's print player_1 and let's print player_2.
Let's just run this and see how we're doing so far.
player_1's name is Michael.
This is Sam.
Okay, so we got, our rolls are rock, paper, and scissors.
Michael and Sam are the two players.
Okay, it looks like that getting information is off to a good start.
Now, let's figure out how to play the game, to do the rolls.
So the next thing that we need to do is we need to actually ask each player what they want to play.
Now, in real rock paper scissors you go one, two, three, shoot and then you both reveal your play at the same time.
It's not easy for us to do that here yet.
So what we're going to do is we're going to ask player_1 and ask player_2, you know, you're going to assume that they're really not seeing that.
We're going to make this more automated as we go.
Let's start out simple.
We'll call roll one is equal to something like this.
We put an input and we'll ask for the player so we want to refer to them by name make it nice and personal, so let's put a f-string here and we'll say player_1, what is your roll?
Rock, paper, scissors, something like that.
So they know that those are their choices.
And then let's do roll two, is player_2.
And that's what they're going to roll.
So let's print out, just a quick thing player with the name player_1 rolls roll one and player_2 rolls roll two.
Again, just going simply along here to make sure everything is working.
So Michael, Sam is what I said.
I'm going to play rock and Sam is going to play scissors and get crushed, by the way.
Cool, Michael rolls rock, Sam rolls scissors.
Of course, I won.
The game doesn't know that I won that round because it's not sure how to do that.
But so far, we're doing pretty good.
I feel like we've got this input thing working alright.
What else do we want in here?
Well, we're going to need to come down here and say test for a winner.
And let's start out with a real simple version where we just play one round and it's all or nothing, all right?
They play their two rolls, each one rolls what they can and then it's over.
Either win, you tie, or you lose it's just all or nothing.
We could also do a little bit of validation if we really want it here.
So, for example, we have those like this.
We could say something like come down here and we could check that what they've typed is a valid roll and this is super easy to do.
We could say if roll one not in rolls remember, we're doing a test.
With if, we can test or whether or not they're just in this list like this.
Here, we're saying it's not in there.
And if it's not, then we're going to print: Sorry, player_1, roll one is not a valid play.
Let's put that right here like this for now.
And, again, for player_2.
Notice that we're reusing this is exactly the same code here as it's here but we're passing in different data.
So it turns out that this is a place that we could really easily check to make sure we're doing the thing right and reuse that code.
But let's just do this.
And then here we'll say I guess we're not doing anything yet but we can just check at least that we're doing it right.
So Michael, Sam, we'll call those two.
Rock, that looks good.
I'm going to go for sponge.
Sorry, Sam, sponge is not a valid play.
Cool, huh?
So we're double-checking to make sure that only valid values are here.
There's not a simple way to say stop without just killing the program at this point.
We'll see when we're doing loops or other things so we can expand on that.
But here we're off to a good start.
|
|
show
|
6:24 |
Well, that was fun.
And now this next part we're going to right here what we have to do is we have to test for a winner, right?
We've already gotten the rows we've verify that they're valid that they are among the three options that we can do with our game.
But how do we test who's won?
Well, it turns out, the most straightforward way to do this is actually really complicated and not very pretty.
But what we're going to do is we're going to build this and then we're going to improve on it and improve upon it, okay.
So let me paste out some little basic steps that say here's how this game is played.
So if somebody plays a rock and then the other person plays a rock, it's at tie the other person plays a paper, they lose.
Other person plays a scissors, they win.
But let's go over here.
And first we're going to need a way to indicate who won this round.
So we'll say winner equals, now in Python if we want to say we don't know what this value is it doesn't point to anything.
Is it player_1?
Is it player_2?
We don't know, it's not set yet.
The way you do that, as you say, it's none.
This means remember in the Python tutor where we had all those arrows pointing at things basically the conceptual idea here is this point nowhere technically there's a thing that's created that's called none, but that's the idea.
So that it says, usually know here this goes right now.
So what we want to do, is we want to convert this bit into some if statements.
So let's do this first one now.
Notice there's a tie, there's a tie, and there's a tie.
So scissors scissors tie, paper paper tie, rock rock tie Though, let's go over here.
And we'll say if, oh, what is it?
Row one is the same as or equal to.
So double equals, remember, row two then we'll print a game was a tie or the play was tied.
All right, so now we want to have another case.
On the other hand, what are we going to do?
Well, we're going to start out by just doing basically this test in software.
I'm going to show you something much better later.
But remember that requires more ideas that we're going to get to.
So if I can say row one, if this happens to be rock now be careful, that and that is not the same.
Though if we say capital R rock that's a totally different variable value than lowercase rock.
So we can actually even verify that a little bit better.
So we could take away some of those challenges that the players might have.
So if they type capital rock or something we could also go over here and say I want to change row one let's make it whatever it is, but we want to lowercase it.
So that's a string thing.
We also might want to say, well if they put a space accidentally and then hit Enter that's okay too, We're just going to ignore that.
So you can say that by saying strip.
That we go to this value, and so by it we say row one is its current value, but lowercase and then take away all the spaces, tabs, and so on.
That'll make things a little easier.
So we don't have to worry about checking whether or not that's a capital or lowercase R whatever they type is always lowercase rock because what we just did there, right.
Now if that's the case we have more tests that we have to do so we have to say if row two is, ah, which one, paper.
If row two is paper, player_1 is a loser which makes player to the winner.
So we'll say winner equals player_2.
Wow, right.
Else, now we could just say else because technically they're not going to be the same.
But let's say make it really clear.
If this is going to be scissors, if it scissors the person whose perspective we're looking at this from is going to be the winner.
The winner is player_1, okay?
We need to just do that over again for paper I'm going to move this up for now.
So you all have this as a little reference.
Like so, and going to be exactly the same.
This is going to be the next one is paper.
This is rock.
It's paper and this is rock then the winner is the person playing that row.
And still like this.
There we go.
So if I play paper, other person plays scissors, I lose.
If I play rock or if they play rock, the paper covers it I win, right.
Do one more and then we'll have it all, okay.
I told you, this is not pretty we're going to make it awesome.
Hang in there.
But right now it's not pretty.
The last one is if I were to play scissors and they play rock, they're going to smash the scissors so they win.
If they play paper, I'm cutting the paper so I win, all right.
And let's just do a little print out here.
So this will be the end of the round, a game is over.
Say if, one more test here, if not winner or something like this, winner is none then what we can do is we'll print it was a tie, else and whatever the winner is, takes the game, right?
Though, we've determined the name of the player.
So that won, we're just going to say they won.
This is what happens if there's a tie.
Otherwise, somebody has won, let's just say who it is.
Wow, okay, that does not look pretty, does it?
Well, we're going to play more of that and make it much, much nicer.
But let's go ahead and play a game and see how we're doing here.
Remember, we're going to build it up kind of the yucky straightforward way and then we're going to make it way nicer with all the ideas like functions or what not that we're studying.
My name is Michael, other players Sam.
I'm going to play paper.
Let's pick some situation where Sam is going to win and to win this round he has to play scissors.
Michael row is paper, Sam row is scissors.
The game is over and Sam takes the game, awesome.
Let's play one more round.
It's getting tiresome to already typed in my name and the other players name, that's fine.
Let's play paper and he's going to play rock which case I should win.
Michael row is paper, Sam row is rock.
The game is over, Michael takes the win with a decisive throw of rock, no, of paper.
Fun, fun fun game.
Okay, so it looks like it's working.
There's a few shortcomings here.
One this is you know, Sam can always just see what I type in and go well you know what it's time to play some scissors or something like that.
The other one is, what if I want to play by myself?
I don't have any friends right now that want to play Rock, Paper Scissors though I want to play by myself so we can make the computer do scissors.
A few basic enhancements there.
The other one, it's very common that Rock, Paper, Scissors is done in a best of style, right?
So, first person to win three rounds first person to win five rounds and so on.
Well, what we've written so far, is not easy to do but we'd have to like replicate this over and over or do some kind of loop or something.
So we're going to do a little bit of work here as well.
More to do but still, Rock, Paper Scissors is coming along.
|
|
show
|
2:37 |
Well this is pretty fun and when we run it, we have to ask for the two people and then we have to enter the two roles that they play.
Well, what I would like to do is have that always be the computer and the computer automatically just play not taking into account what I've typed but what the options are.
So that's what we're going to do in this section here and it's super easy.
We're going to need to have the computer make some kind of random selections.
So we already saw the random library, that had randint.
We're going to use the random library again.
We'll import random.
Remember, pretty much enough to type r and that's it.
Right now Pycharm has it gray and what that means is you're importing this library but you're not actually using it.
It's unnecessary, your code would work just fine if you were to take it away.
If I hit Enter, it'll just clean those up cause it's like, hey this is unused.
But that's just because we're about to use it.
So, for player name two, instead of asking let's just say this is the computer.
And then, we could even simplify this and make this just you, for now.
Here we ask: Hey you, what is your role?
And then, we're going to get something.
And down here we're going to go instead of asking the player for an input we're not even going to need to validate it cause it's always going to be valid.
What we're going to do is, we're going to use that random library.
Now, there's ways in which we could use a random integer and the length of the roles and all that but Python has a much better option.
We can just say random, and we don't have to type all of it Pycharm will help us there.
If we have a list like this, of multiple items and we want to randomly get one of them all we have to do is say choice.
And, we can come over here and just say choice and give it.
As I say it take a sequence, well let's give it rolls.
Perfect.
So, we do this, it'll say: You roll Make it like this You roll that and the computer rolls this.
All right, let's give this a shot.
Will we have it working?
Notice also I've maximized this just a bit more just for more room here.
Okay, you want to do your roll.
Maybe we want to ask for your name again.
We will later.
I want to play paper.
You roll paper, computer rolls scissors, game over!
Computer takes the game, cool.
Can you see how incredibly easy that was to have a computer opponent random?
Random choice and just set the name, that's it.
That was it.
Now we have a computer opponent.
It's kind of crazy Of course, it's not very smart, it's just random but you know.
There it goes.
The idea though, is that this function choice that take data and returns data allowed us to work in an incredibly simple way.
I'm sure the actual details of choice is not too complicated it can't be as complicated as the random number thing but maybe actually use that deep down inside.
So, here we have a computer opponent by just using this function.
|
|
show
|
5:42 |
Well, this simple version of rock, paper, scissors is cool.
We can play it.
It has a computer component but there's, again, some shortcomings here and boy is it not pretty to look at.
It's hard to think about what's going on 'cause you have to read every little detail.
Like for example, wouldn't it be cool if this could just be all hidden away and that just said Get the rolls?
And this part down here could all be hidden away and it just says, Get me the winner?
Well, let's do that next.
So what we're going to do is we're going to define some functions.
We're going to start up here and define a function that uses the other ones.
So that allows us to sort of say the high-level things.
It allows to say first the program does this basic thing and then it does that basic thing and you don't have to worry about the details unless you need to get into them.
So let's actually create a function that just does this and then we'll use it from the top pieces.
And it's really important to have a good name.
So what is this doing before we say what we're going to call the function?
It's printing out the header for the program like the message at the top so let's just call this print_header.
The way we do this in Python is we use a def keyword.
Define function.
So we can say def and then whatever name we want to make up like show_header like this.
It's a pretty good name.
The next thing we have to say here is what data is passed to it.
What information is provided to this function so that it can properly show the header?
Well, it takes None.
So if you wanted to take None you just do open, close parentheses as opposed to a, b like random int but we don't want that so we're going to do this.
Now again, this is one of these code blocks and if you want it to work and the stuff to be in the function you have to do this indent like here inside, okay?
So we want these three pieces inside and the quickest, easiest way Is to highlight them all and just hit tab and that indents them.
Okay, now it's a little unhappy about the spacing.
Remember that's just the code style that we can fix automatically.
So, here we're going to print the header.
That's the first thing we're going to do and lets go over here.
And were going to have this high level thing.
We're going to call it main.
I'm going to create another function called main and the first thing it's going to do.
It's going to do show_header.
Cool.
What is this doing down here?
Well, this part here is maybe going to play the game.
Guess we'll just call this play_game.
Def play_game.
It doesn't take any information.
Maybe we could even pass like the names of the player or something like that.
Let's call.
Let's do that.
We'll pass in player_1, and player, player_2.
And notice these variables are down here like this but instead of having them hard coded here.
We want some high level part of our program to decide what players there are.
So, we'll go over here and do it like this.
If we just go down for the moment and indent all of this.
This is highlighted cause it just wants some spaces here like so.
And this.
Next thing we're going to do is say play game and we can get player_1 and player_2.
And notice this has a little warning or error that says You have to tell us what player_1 is.
I'll call this player and AI.
Let's just give them different names and the variable names they have down here.
So, we're going to pass for player_1.
Player, we're going to pass for player_2.
AI.
Now, if you look at this.
This is quite a bit simpler.
It says what we're going to do in this whole program.
Forget what this is.
Forget how that works.
Get all the details.
Let's just do the high level picture of what's going on.
We're going to say going to show the header and then we're going to play the game.
And play game is also complicated so we're going to break it in to smaller pieces that are easier to think about as well.
Let's go running.
I think it's going to do something fun and interesting or exactly the same basically.
But no that's not what happens.
It stopped working.
Why did it stop working?
Well, in Python it turns out that there's no convention to run one of these functions so at the very very end you have to make sure you execute the top level piece to get it to run.
So we'll run it now.
You, what did you roll?
I rolled paper.
Great, computer rolls rock.
We take the game with that decisive paper throw.
Pretty cool, huh?
Now, this is fine.
But, there's this convention that we use in Python because if we wanted to re-use some of these libraries some of this functionality we've written here.
This is basically going to prevent that.
Cause if we try to load this library it's going to just start running the game.
Which maybe we don't want.
Maybe we want to re-use this bit.
Like we use randint.
So there's this funny weird-looking convention that says, only run this function here if I'm trying to run this file, this program directly.
Someone else, some other part of the program is trying to use it just define the functions but don't do this part.
And the convention is built into PyCharm.
So if I type main, notice there is one up at the top that's the function I wrote.
But this one is something else.
This is what's called a live template.
PyCharm will just write that for us.
And it says Here's the convention.
There's this thing called __name__ and if it gets set by now which when you run it directly but, is not done when you don't run it directly.
So this is a way to test.
Only run it if you're trying to use it as a program.
Finally, let's run it one more time.
Hey, it works.
Rock again.
They roll scissors.
Game is over, we crush them with a rock.
Awesome.
So we've done a little bit of organization, but notice this 19 to 72.
There's a lot of stuff going on in here.
We're going to make this a lot cleaner and nicer and break it up into pieces as well.
But we're off to a good start.
Defining these functions which we use a the def key word.
Give them a name and they either take no arguments.
Or we define them, give them a name and they take one or more arguments.
There's actually a lot flexibility what you can specify they take what is optional what is required and so on.
We don't need to go too much into it but what we have here is probably a good enough example for most functions you need to write.
|
|
show
|
5:58 |
Up here we're able to give a high-level overview of what's happening in this program or our main but our play game is still kind of like the rest of everything.
It's a bit of a mess.
So let's go and work on making this cleaner.
Now, this part right here, this whole section is going to give us the name of player_1, right or the roll of player_1, sorry.
So let's go and actually make that something much simpler.
Instead of looking at all of this stuff here what we want to do is we want to create a function that would just say get_roll and it's going to ask player_1, What is your roll?
Now, there's a couple of things that we're going to have to do.
Notice that it's working with rolls.
If I click here, you see it highlight.
Notice that it kind of colors all the places it's used.
But it's working with rolls.
It's also working with player_1, which is passed in here.
So in order for this to be a function it has to be provided those two pieces of data all the rolls and the name of player_1 because those are going to be coming from other places.
Let's go down here and do that a def get_roll or get throw.
It's have to be player name and it's going to have to have all the possible rolls here.
And then we're going to put something here.
If you don't know what to put yet the thing to write in Python is pass.
That means it does nothing for the moment.
Let's go over here, and let's just grab that.
Want to say roll one equals get_roll.
We need to pass player name.
So that's player_1.
And all the rolls, we're going to pass all the rolls.
Notice we can't define the rolls down in that function 'cause this part also needs them, right?
Now, there's a squiggly here saying You're not quite done with your function.
We know that.
So I just copy that bit down here.
I'm going to paste that like so.
Now, I change the name to make it sound more general 'cause this will work for any player if we want to have competitive players against each other.
We're going to do that.
Again, for the same reason, this is not roll one.
This is just the roll.
So what we need to do is everywhere we see highlighted down here, this needs to be renamed from roll one to roll.
Now, we could do it manually.
It's only four or five spots here.
It's not a big deal.
But you want to make sure you don't miss something.
You want to make sure you get it exactly right.
So PyCharm has this cool feature and it's a general idea in programming but it's built into PyCharm to do what's called refactoring and that is to change your code in certain structured ways without making it mean anything different.
So watch this.
If I right-click here and I say refactor, rename if I go over here and I type take that away notice it changes it everywhere.
And I could have anything I want and it makes sure all the code that was trying to use roll one is going to be continue to be consistent with that.
Cool, huh?
Okay, so and to make it stop, you just hit Enter.
Now, that's a pretty good start.
However, we've got this information.
How do we give it back?
How do we go to whoever's trying to use this function and say, Here's the roll they selected?
Now, that's the last step down here.
We have to say return.
This is what value did the function create?
What does it provide back as its functionality?
We're going to pass back this roll.
If we go back up here, this little squiggly went away because what it was saying was this get_roll that you're calling, it doesn't return any information.
It doesn't tell you anything and yet you're trying to set roll one equal to a function that gives you nothing.
But now it does give back something so PyCharm is again happy.
So here we're getting our two rolls.
This function is really interesting 'cause it takes two parameters like we saw before but it also has a return value that we can use.
And here in this context this is meaningful as roll one, not just a random roll.
There is one other thing here.
Notice here where we say, There's a problem.
Sorry, you can't play that.
Let's tell, instead of returning whatever that was we'll return none.
So this is a way we can say back to who tried to call it hey, we tried to get a roll from the player but they gave us something nonsensical so it doesn't mean anything for us.
We're going to just say we got nothing.
And down here, we can do a quick test.
We'll say if not roll one, print, can't play that, exiting.
Here we can just get out of this game early by just saying return.
There's no data, so we don't say return roll or anything.
We just say get out.
And this will make it stop.
So this will actually solve one of the problems that we had before.
Go ahead and run it, see how it's working.
Whew, okay, so you, what is your roll?
Gosh, that's kind of weird to say.
This is the function that we just wrote.
That is this get_roll on line 22.
So let's say paper.
It passed back paper here to roll one it checked that that was okay, and it said player_1 rolls player_1 is you, you roll paper.
Awesome, right, so it looks like that worked.
And then it comes back and it does a test and you takes the game.
Yeah, this is a little weird, this name thing.
Cool, though, right?
So what we've done is we've taken something that was kind of complicated, like four or five lines and it also had this problem about how do we get out of the game early?
We condensed it down to just this idea of get the roll.
All the validation is checking is there talking to the users there, all that and we don't have to think about it.
Now when we think about playing the game all we got to know is you get the roll from the player you randomly get one from the computer.
Boom, off it goes.
So getting this input from the user is much, much nicer.
And down here if you need the details, you can go see them.
But if you don't, you can just collapse it away and think, okay, get_roll.
I give 'em a player name.
I get a roll.
Give 'em all the rolls.
I get one, a validated roll back, or I get no roll.
And that's why these functions are often referred to as black boxes.
You know what goes in.
You know what comes out.
And if you want, you don't have to go over here and peek at what's actually happening.
When done right, you can hide it away and say I just know what get_roll does.
It's going to get me a valid roll, or it's going to get me none.
I think that's pretty cool and it's a really nice way to think about playing this game.
So this part is much, much simpler.
We still got to deal with the winner bit but we're making good progress by simplifying our play game.
|
|
show
|
4:40 |
Well, the first part of our play game is much, much nicer.
This line 22, get the roll validated from the player.
And it gets us a chance to get out of here if that doesn't work.
This other part of checking for a winner makes up a ton of stuff over here.
So all the way, this reporting this is not really getting the winner this is more about reporting who won.
But from here all the way to there that blue bit, that is the code along with a comment that we wrote, to get the winner.
So what we've done so far, is we've gone and said Okay, well let's make a function.
I'm going to go type def, a thing I want to call it.
Figure out parameters go in there, what gets returned.
And it's very manual.
And you need to be able to do that.
You need to do enough practice so that that makes a lot of sense for you.
But once you get used to it, you can leverage tools like PyCharm, to make this much more error free.
Okay, down here, remember, in this section I said, I want to rename roll.
So I'm going to use this refactor idea to make sure that PyCharm can verify every bit where we're using roll, roll one.
If we want to rename that we do that in a consistent and valid way.
But with functions, we can do that even better.
So watch this.
So I want to take all of this and that winner and test.
So let's look through that process again.
So it's going to take roll one and roll two it needs that information.
It needs to know player_1 and player_2.
And then it has to give back the winner so the winner can be used here.
So watch this.
Don't have to use this tool but it's super cool to help you when you're getting started or when you're a professional.
It'll be good for a long time.
So extract method this means take all this code I've highlighted and create a function.
Give it everything it needs to get started and return what it needs to return.
Beware, this doesn't always work.
Sometimes things are too complicated to make sense to do this automatically.
So, let's see what we get.
So it says we're going to have a extract.
Extract method is going to need a name this is the name we want to call the function.
We'll say, check_for_winning_throw.
And notice, it says it takes player_1, player_2 roll one, and roll two as you would expect there.
And let's make this a little taller.
It's kind of weird, the way it's getting squooshed.
Well, whatever.
It doesn't want to resize.
So then notice the output variable is winner.
And if I hit okay, watch this.
Boom, all that stuff, all those complicated lines are reduced down to this.
check_for_winning_throw.
Give it player_1, player_2, and roll one, and roll two.
And then it's going to come back and do the same test with the data, here, that is returned.
And then down here this is the thing that was created for us.
Right?
All this code down here was written by PyCharm when we said extract method.
So that's pretty cool, right?
We could leave this comment up here.
Probably this check for winner test for winner, is not necessary because check for winning throw already tells us.
We could leave these comments here if we think they're going to be helpful probably they are for now.
So let's just leave that.
Now, we've changed our code in a way that's way cleaner like hide that away, hide that away.
Now we can look at this and we can say Okay, what does our program do?
Choose the header, comes up with the two players and it plays the game.
And we could actually do this as well.
We come down here and just write in place, you and computer.
Like that.
And we don't even have to explicitly do that.
So we're going to show the header and play the game.
Play game is made up of getting the rules and getting the rule validated from the player.
If you can't play, you can't play.
We have this little print out, so we know what's happening.
And then we check for a winner.
It doesn't matter how complicated that is.
As we'll see, it can get more complicated or better as we work on it.
And then the game is over depending on how many people have won.
Let's try that.
It should behave exactly the same but it is much easier to think about.
And you'll see that it's also easier for us to add the best of five, or best of three, or whatever.
I'm going to play rock.
I threw a rock, paper throws rock.
The game was tied.
So look, it still works, just like it should have.
Let's do one more.
Scissors, you roll scissors.
Computer rolls scissors.
Now the computer rolls rock.
Game over.
Ah, we lost.
But we won the game of programming, didn't we?
Look at this.
Look how much nicer this is.
And if we need to check for winning in other places or we need to get rolls in other places we just do that one line again.
And it allows us to have a simpler code that we think in high levels about but also to reuse it.
'Cause if you want to call it again there's your player_2 against player_1 in a manual way.
Right?
If you wanted to play computer we could just come down here.
And I play rock, they play paper, boom, that's it.
Look how easy it was for us to convert from an automatic player over to one where we have a multi-player sort of situation.
And that was easy because this code is incredibly reusable.
All we got to do is call the function again with different inputs, boom, we're off to the races.
|
|
show
|
6:36 |
Well, our winner-take-all-thing was fun.
But like I said, this is not typically how rock-paper-scissors goes.
Usually, it's best of.
So let's go over here and have rounds and let's say we're going to play best of three.
This would be how many rounds you played.
And then in order to figure out somebody has won the overall game we have to know how many rounds they've won.
So the first person to win three rounds is going to win the game in this case.
So we'll say wins p1 is 0 and for p2.
It's a little clumsy.
We're going to come up with a better way to do this.
But, again, we're taking sort of iterative little approaches to working on this.
We're doing simple stuff then we're adding more ideas and more programming concepts.
Data structures will let us simplify a lot of these things going on here.
So what we would need to do in order to play the game is, well, we need to go have a loop.
And we already did one, these while loops.
And let's do a little test here.
We'll say, first like this, we'll say while wins_p1 < rounds and wins_p2 < rounds.
'Cause if they're equal that means either player_1 or player_2 has won.
Then we want to do something like this in the loop.
But we need to record who won that round and this also, we kind of want to just print out maybe not the game, but the game is over this round, this round with a tie takes the round.
Then down here, we need to do a test.
So we'll say if wins one is greater than or equal to rounds print a little output like So, player_1 wins the game else player_2 wins the game.
Right, so this is a start here.
Now, the one thing we have to do is figure out who has won the game then update that.
So this is close, we're going to have this but we have to say something like this.
If winner is equal to player_1 then wins_p1 has to get bigger by one.
If it's two, we want that to be two.
Now, this could be else, maybe if else makes sense but it could just be else with no test but maybe we're going to have three players in the future or something, I don't know.
Let's keep it a little bit like that.
Down here, we could do a little bit better as well.
We could have something like this.
Overall winner, both none.
This would be player_1.
And we can just print out overall winner.
So what was less good about it before?
Well, what if we want to change the text of Wins the game or other messages like that we'd have to edit it in both locations.
Writing it like this means that this is only expressed once.
All we have to do is figure out what name goes into the statement which is a little more safe and less repeating ourselves and so on.
Okay, so do a final cleanup.
This is cool.
We should be able to have this work once again, I guess.
Yeah, I think this is going to do it.
Let's go and give it a try.
There's probably a little good message we can put out like Hey, it's round two, it's round three and so and so is in the lead, or something but I think this will work.
Okay, round one, what is your roll?
I roll rock.
You roll rock.
That takes the round.
What is your roll?
On this next one, I roll paper.
I roll paper, computer rolls paper.
So now that should be one win computer, zero wins me.
Let's actually print them out down here.
We print score is player_1 and player_2 is win_p2.
Let's do a little separator as well.
Okay, so now we'll be able to track this a little better.
So paper, we roll paper, they roll scissors oh, I got crushed.
The score is you zero, computer one.
It's round two.
Let's go and say, well, if they rolled scissors I'm going to roll rock.
Of course, it's random, it doesn't matter.
They win.
Okay, if they win one more round and our program is right, it should exit.
But let's say scissors I do scissors, they roll rock.
The computer takes the round, three-zero I'll get out of the loop because this test up here somebody has won.
I'm going to get out of this loop.
And then that's it.
The computer wins the game.
Let's do one more just to see how this works.
I'll play a lot of rock, I won.
I'm up by two, two to one, two to two.
Here it goes, somebody's going to win.
Rock, oh no, maybe not, not if there's a tie.
Oh, the computer won again.
But pretty cool.
You can see even when there's a tie you know, let's just play again it's the best-of-three wins not just whatever happens after three rounds.
So there you have it.
We now and we're able to use this again over here to this.
There's one other thing we could do that would make this a little bit nicer.
So this is starting to look a little complicated again.
All of this stuff here it's like well, what is going on here?
So let's do one more thing.
Let's maybe make this, could be something like play a round.
So we come over and we're going to right-click and say refactor and see if this is going to come up with something reasonable.
No, no, it can't because this part right here.
So that's okay.
Now, one thing that happens is if this is wrong before it was just canceling the game.
If we want to say, you know what, we can't do this but let's just go and ask again we can change this Return to Continue.
What that means is instead of going on down this way oddly, Continue means go back to the top go back up here and just start again and then start again until you get past this.
So let's do it one more time.
If I play blah, blah, blah, sorry, that's not valid.
Can't play, exiting, I guess.
Let's just say Try again.
Try to play blah, blah, blah, nope.
This one, nope.
Rock, there we go, you play rock and scissors.
So I think our game is in pretty good shape.
Again, I think we could clean this up a little bit but there's not a whole lot to do.
It's about as good as it's going to get.
I like it.
It's so much better and reasonable and clear to understand than when we first started, I think and we got through it.
This used to be like complicated.
It's just that.
This was super complicated, now it's just this.
Pretty cool.
So hopefully, you can see how functions made our code easier to think about.
We don't have to think about all the details of checking if we're winning through as we try to understand what this loop does.
When you have to think about all the details of getting a roll all we have to do is no, first, we got to get the roll also have the computer play the roll and then check for a win and go and do something based on that.
|
|
show
|
2:01 |
Let's review this concept of functions and functions that take inputs and have return values.
We're going to encapsulate the idea of playing around.
This was basically the inside of that loop that we built in the previous example.
And in order to do that we're going to have to pass in the names of the two players.
Here we just embed, or have, the roles right here.
This is kind of isolated so it's not exactly the same as before but we have these three roles and then we're going to print out what they were just so that folks can see what roles they can play.
And then there's some logic to find the winner that's probably getting to role from the one or both of the players.
And then, comparing whether or not you know, if they rolled rock did the other paper roll paper?
Whatever it was, once we figure that out we set some variable we're not talking about explicitly.
player_1 wins, or player_2 wins.
And if player_1 wins, we're going to return player_1's the string or the name of the player otherwise player_2.
And if player_1 doesn't win and two doesn't win well, must be a tie.
So we're going to return none like we did before.
This is a bit of a simplification but the things I want you to take away here are we start all functions with the keyword def.
D-E-F.
And then we have a space.
And then we give it a name.
And this name can be any valid, variable, name, in Python.
For example, it can't start with a number but the rules are pretty open, right?
After that.
And then it's going to take zero or more pieces of data.
In this case it takes two the name of player_1, and the name of player_2.
And then it's going to return some data.
Now when we talk about the function up at the top line we don't indicate returning any data.
Some languages do, they actually say This function takes these two players and it returns you know, the name string, or something like that.
In Python we don't do that.
We just either return it or we don't.
So down in the bottom we're going to either return a string or we're going to return none.
So we can check whoever calls this.
Did somebody win?
Here they are, otherwise, nobody won that must be a tie.
This is how we create simple functions.
And they're incredibly useful as you saw throughout that example.
|
|
show
|
6:42 |
Let's look at what I consider to be a bit of a drawback for our game here.
If I run it, I have to type scissors.
And if I misspelled scissors, like 'ssors then, whoa, whoa, that's not a valid play you got to go again.
Wouldn't it be nice, wouldn't it be easy, if it could just press one for rock two for paper and three for scissors?
That would be cool.
That's what we're going to do now.
Also, going to let us look at a cool different type of loop while we do it.
Now, let's go back here and kind of go through this higher view of our program that we have because we're using functions.
So show header, we don't need to mess with that.
play_game, that's probably the place we have to go.
And then in here, this is the part that asked the user to input something and then it gets it back.
So all we have to do is change get_roll and if this was used in many different places this change would automatically be picked up everywhere.
That's cool.
So we're going to jump down here to this and what we can do is instead of that doing that, there Let's go and show them the rolls.
So I'd like to print out something...
I'd like to print out what various role options there are so there's a really cool way to do that.
Anytime you have a list or some sort of collection or sequence of things you can go through it using what's called a for in loop.
And it's incredibly simple, all you do is say something like this for r in rolls.
Each time, for each role, there's three...
So this sweep will run three times you can just print r Let's just print it like this for a second.
Let's go and run that and see what happened.
Here we go.
Look how cool that is.
So all we got to do is, for thing in collection now work with the thing.
Well, that's not a huge difference, is it?
It just puts them out, top to bottom vertically instead of horizontally.
So let's not do exactly that.
Let's add a little bit more to it.
What I like to do is show a number.
Now, we could come over here and do this weird thing where I have index equals one.
We could print a little f-string here.
So we could say curly, and we could say index not, and then the roll.
And here we could have it get bigger by one.
Here we go.
123.
That works.
But it's very much not the right way to do things in Python.
So instead, let me just give a little head right here.
You can get spell checking, by the way, which is cool.
We go like this.
So instead of doing this, what we can do is we can say I would like to get the object and it's index.
The way we do that is we say enumerate and we pass the thing we would have looped over and we get back here is two things.
We get the index and the role.
So forget that part right there.
If we run this, it's going to do exactly the same thing but we don't have to do extra work to do sort of bookkeeping of those numbers.
Close to what we want, but not quite.
012.
All the numbers in Python start at 0 indexes start as 0, and so on.
So this might be fine but its a little weird for people it's also not very handy for putting your fingers near the numbers.
So what we can do is we can say start equals 1 and this is a way to pass data to this enumerate function and be more explicit.
Say, there's a bunch of things that have default values I don't care about them, but this one called start let's set it to 1.
We try again.
Boom.
There we go.
123.
That's great but the input is still expecting us to type in rock, papers, or whatever.
Instead, let's change this...
elected index or something like that.
And in order for this to be, remember, a number not a string, that just looks like a number we have to convert this input to there.
So we could either wrap it like that or we can come over here and make a separate variable so it's more obvious.
Actually, what did I call it?
I called it test.
There we go.
We could be like this.
Now we don't have to ask them for the roles instead we have to ask something else.
So what we need to do, is we need to know that this number is going to be between sort of one to the number of roles but remember what did I just say?
That indexes start at zero and they actually go up to 1 - length, it's a little bit weird.
It takes some getting used to.
So we need to adjust that back to convert from a human thinking, from 123 back to computer thinking, 012.
It's a weird thing but it happens in almost all the programming languages, so we'll just go with it.
And then instead of this role thing here, we'll have to say if selected index < 0, <= 0 or selected index is >= Actually, zero is okay because we adjusted it.
But if it's great than the length of the roles...
That's how many lengths there are in that collection the way we do is like so.
Let's change this to selected_index + 1 so that in their mind Hey.
They still see it as that one they've selected and we could actually just put text.
That would be easy.
It'll say it's out of bounds.
And then here we need to return the role from the index.
The way we do that is we go to this collection.
We say, I know you're a bunch of things I want to get one at a certain position that we've selected but we'll just say selected index, like this.
Go to the collection.
Pull out the one that they typed in.
This way they don't have to type scissors, rock or whatever we end up expanding this to in the future.
You just type 123.
Let's try that.
Which one do you roll?
How about two?
We say two, you roll, paper.
Cool, right?
That was rock.
Okay.
Score is we're up one, we haven't won one of these yet so that's cool.
Let's play scissors.
There we go, we rolled scissors.
We'll roll scissors again.
Oh, computer won.
Let's roll scissors again.
Let's play one, throw some rocks or else we're in trouble.
Hi.
This is it for all the marbles, unless we tie.
Whew, it was a tie.
Let's throw rocks again.
Man, we haven't won one of these games yet, have we?
Crazy.
But there it is, at this cool way of working with four in loops, allows us to list out all the items.
Because we want to give them a number we can use enumerate and say go 1234 and give me the item that goes with it.
Let's us ask the player for just some kind of number in a one, or a five, or whatever the possible options are.
I guess we haven't tested our logic.
If you enter five right now, it's out of bounds.
We enter zero, it should be out of bounds.
Not for the computer, but remember we adjust that to be one fewer.
We put minus 100, still out of bounds but one, one works.
|
|
show
|
1:55 |
Let's review this idea of for in loops.
The for in loop is excellent for going through a collection of items.
This is extremely common in programming.
In programming you'll be given a bunch of stuff and you're like, well, I have to go through each one individually and do something with it.
Maybe the user typed it in.
Maybe it's a file, you want to go through every line.
Maybe it's something you got off the internet.
You call some API and it sends you back a bunch of data.
Who knows what it is?
But you go through them always the same way.
So here we have plays, which is a collection a sequence with three items: rock, paper and scissors.
We want to go through each one and show them to the user.
Here we're going to actually print them on the same line, so there's this cool trick we can do with print and we can say end instead of being a new line a line break, it can be a space.
For each time we do a print statement it just piles up on the end as a space.
You could put comma you could put a dash, whatever you want.
So we're going to say for p in plays.
We're going to print that out.
Rock and then paper and then scissors.
That's pretty cool.
But a lot of times we need to actually know the number.
Like, we're asking the user, enter one, two, or three and then that will correspond to rock, paper or scissors.
So if we want to do that, we go and have the same for in loop but we use the enumerate keyword and we can control the start position.
Talking to humans, usually start equals one.
If you just need to know the index in the list then leave it alone, you'll get zero, one, two, three.
And then we have two elements that come out into our loop there, so we say four idx comma p so index and the play is going to come out and then we can work with them both at the same time.
You'll see these loops everywhere.
They're super, super common.
They're the other type of loop that you have in Python other than the while loop.
While loops are great for I want to do a condition as long as something is true but for in loops are super powerful because they let you take a collection of things and work with them, each one of them individually.
|
|
show
|
1:43 |
Now that you've seen the power of functions both for re-using code allowing you to work on it in one place but affect it in many places that it's used in your program and treated as a black box.
Just, here's a core idea that may be complicated but all you got to think about is what goes in and what comes out, for example, check for winning throw.
That was super complicated, but we just passed in the plays and got the winner back.
That was nice so let us think about our program in a much higher level.
So, I put together some practice exercises for this chapter, as well.
I think you'll have a lot of fun wit this one.
A pair of core concepts that are very close to each other and that's just about creating functions.
Here's a function that takes a parameter and uses it.
Here's a function that has a return value it gets the data internally creates it and then gives it back.
And we can even use these together like we can use the get name one to actually get the name and then to say hello to greet the person after they've given us their name.
So, here's a couple ways in which we can do that.
For this exercise, your job is to take the M&M guessing game which you'll recall it was written with no functions just all jammed together created back in CH05 before we talked about functions.
And clean it up, using functions.
Now, if you look in this folder in practices, CH06.
You can see there's a copy this.
I put it here just to make sure that it's right here and easy to get to.
If you go here, you can see it's doing things like printing out what the game is some information.
Getting some random details.
Playing some rounds, checking for a winner.
These should all sound kind of familiar.
And you could use functions to make it a lot nicer.
So, that's your job, take this code make a copy of it somewhere make it better with functions.
|
|
|
32:50 |
|
show
|
0:58 |
It's time to talk about some of Python's built-in data structures.
Now, this is going to be a really fun chapter because what it's going to allow us to do is to take code that was kind of ugly and hard to write and tedious and reduce it down to much simpler ways of working with the same type of data.
Now, data structures are really important.
This includes dictionaries, lists, sets and other types of data structures that you might've heard of.
Freeze, for example, there are many, many of them.
There are a few core ones in Python that we're going to touch on in this chapter.
We're going to take and improve our rock, paper, scissor game and you're going to learn all about them.
Data structures are fun because these are some of the ideas and techniques that really separate beginners from professional or experienced developers.
Once you know how to use these and once you know they exist they can dramatically simplify your code make it faster, make it less error prone all of those things, all at the same time.
So I hope you're excited to dive into it.
You're going to see some very cool stuff develop within our game because of them.
|
|
show
|
2:31 |
As a user rock, paper, scissors is a pretty good game.
It's a decent rendition of the real game that kids used to play all the time to settle scores decide who gets to sit in the front seat or has to sit in the middle in the back.
But as a piece of software, it has issues.
Lets take a quick look at just one of those.
Remember this play round where we're actually trying to figure out whose the winner?
When you get the rule of the first player the rule of the second player and then there's this huge ugly, complex thing.
I mean just, oh my goodness.
This is rough.
So if you think about having to read this and understand it or verify every single case is correct you know if I throw a paper, and they throw a scissors are you sure that's right?
Are you sure?
It's not easy to verify.
So this part here, this red part.
This is the trouble, what are some of the problems?
Just some.
Well it's hard to read.
It's not easy to just quickly skim through and see what's happening and make a lot of sense.
You've got a whole lot of ideas in your head.
You've got the outer if else if, else if and the inner if else if, else if.
You got the names, name zero, name one, who's who and so on who threw what.
So it's a little bit tricky it's hard to read.
It's also hard to maintain, you need to make a change in the software like I said verifying that every aspect of it is correct, that's a challenge, again hard to verify and not extensible.
In software extensibility means the ease or ability to add new features or new capabilities to the software.
What if we wanted five way rock paper scissors?
We want rock paper scissors sponge and wolf I don't know.
We want to have all those things play, think about how much more complicated this gets, how much...
You know all these things sort of compound it's hard to verify that adding those new features is working right and so on.
What we're going to do is we're going to rewrite this using something called dictionaries and it's going to get dramatically simpler and even more interesting to add new features to it to add five way, seven way, even 100 way rock paper scissors we'll have exactly the same code and it won't get any more complicated.
Now the data structure describing the rules basically will be slightly more complicated for each one of course but not nearly the degree at which we have here.
We have in this case we have some form of common notarial problems, so if we have five plays instead of three we have five outer if's so that's two more, but we also have five inner steps and branches in each one.
So we have 25 bits instead of nine like we have here.
So as we add more it gets multiplicatively worse in this case and what we're going to do with dictionaries is it'll be just the same, it'll be wonderful.
|
|
show
|
6:16 |
Before we dive into working with our rock, paper, scissors game and these data structures let's begin by just working with the data structures in isolation so we can focus on that.
So over here in our GitHub repository we had CH06 and here's our game we built.
I made a copy of that over here but I also made a empty folder called simple dit.
In here, we're going to put some Python file that we can work with in on macOS only there's a cool little bonus you can drag and drop this here and it will automatically open that up.
On Windows or Linux, you have to Save file Open directory and browser.
Not a lot harder but it is a little bit.
So we're going to come over here and add a new file just call playground and in this playground I want to introduce you to some of the data structures.
The one that's most important is this thing called the dictionary.
Oh it looks like we got to add a Python interpreter.
Now that we can run our little playground because we set up Python for some reason and gotten lost, no big deal we're going to play with this idea of dictionaries.
So we have a couple of different data structures.
First one that we're going to work with is dictionaries.
We also have this idea of lists or arrays.
We've already seen those.
We worked with those.
Those are like [1, 1, 1, 1, 7, 11].
Something like that and then a third one is going to be sets.
Sets, lists, and dictionaries.
These are three that are built into Python that are super, super useful.
So we're just going to quickly go over the lists and sets because we're actually going to focus on dictionaries.
Now the lists we've seen that we can have let's just do lst like that.
Don't use the full proper list because list is the name of the variable or the class that you create so we want to not get in the way of that.
We might have just that thing I wrote there.
Let's put 'em in a different order.
We can print out the lists.
It knows how to print itself and so on.
Let's see what that looks like.
We can see that.
It also has cool features like all sorts of stuff you can do.
We can append an item to it like 15 and then if we print it again you'll see now it's added this item.
We can also say list.remove 11.
let's print that out again.
Now 11 is gone.
We can also say, actually let's pend to just something so it's not in order.
We can also say list.sort and then print the list one more time and that'll sort it.
So there's all sorts of cool stuff and then we saw that we can use these in a for in loop.
But these are lists here, very, very common.
Sets are also simple and interesting.
So a set is something like this.
Let's go copy that.
It's like this except for the way we create it is with curly braces.
Can also create dictionaries with curly braces but when you have individual items not pairs of items in here then it's a set and the point of a set is it's a collection of items like this.
And you can loop over it and you can print it out but the difference is it's about distinct items.
It has one and only one of them.
If I go over here and say set I can add one.
I can do that three times.
I can even add 11.
But what you see come out when you run it is 1, 11, and 7 because it doesn't matter how many times one is in there you just want to know is one in there, yes or no?
So this is looking for distinct items in a set without duplication.
Those are very interesting.
The third one and the one we're going to use the most in this section here is something called a dictionary.
A dictionary is kind of like a set but what it does is it lets you give a name or what's called key and then quickly look up whatever value you associate here.
So let's say we're going to have just d for dictionary then here we can say the key is going to be Bob and how many times Bob has won a game and Sarah, how many times Sarah has won the game.
Initially when they start playing or whatever they're not going to have any wins.
So I can come down here and I can print out how many times Bob won by saying like this.
I can go to the item and put a key in here and it should come out with whatever that is.
Here is the 0 and we can also update when I come down here and say += 1.
Print it again.
Now Bob has won once and if we print out the whole dictionary you can see now it has Bob is 1 and Sarah is 0.
If an item, something like this, doesn't exist and you want to add to it, you could say this: Michael, I'm going to cheat and start out at seven.
How about that?
But can add me in there and if I run this, what do we get?
Michael is seven okay.
This is really useful.
We'll be able to do things like come over here and we'll be able to have wins or defeated by.
And here you can put interesting stuff like I could put a set.
It doesn't have to be a primary or scale or numbers like this.
Suppose this is the dictionary for rock.
Well what is rock defeated by?
Rock is defeated by paper and it defeats scissors, okay.
And it could if we had like wolf, you know, we had that example when we had sponge or whatever we wanted to extend this like so then you can see we can just add to it.
So if we wanted to know hey what are you defeated by?
Put a little f-string here.
Now if we run it, you can see you are defeated by wolf and paper.
Pretty darn cool.
So we're going to be able to use this data structure really, really easily and to sort of gather up and encode in the data structure instead of code itself the rules of our game, and then we can save these data structures to a file which will be really, really cool.
Final thing I want to show you is if I get something that's not in the dictionary we get a key error, fully crashes our program.
If you're unsure if something is in the dictionary you can use this keyword get and we can print that out and you just get none back.
If you want to say, Oh you know if the thing is not there give me 42, otherwise give me the value, you can use this more advanced version.
So use this style if you're sure that stuff is there or you want to write to it.
Use this style if you're unsure if it's there and you want to check, Hey is that none or is it something?
Okay so these are the three main data structures of Python.
We have the dictionaries.
We have lists, similar to arrays in other languages but they're called lists here.
And then we have sets.
Lists are for getting items in order, keeping them in order and accessing them.
And we can get the third one by saying list bracket two.
Remember zero-based sets are about distinct elements.
They do intersections and differences and stuff like that.
And finally dictionaries are given a key.
I want to find value quickly.
|
|
show
|
1:48 |
Let's quickly review dictionaries, as that's going to be the focus of the rest of this chapter.
To create a dictionary, we can either use curly braces or we can use this dict().
Just like we can also use list, instead of square bracket.
Like we did in the demo, we can create a dictionary with the curly braces.
We can create a dictionary by saying dict.
Now you might wonder if we can also create sets using curly braces, and we say curly brace.
What do we get?
Well, it's decided that dictionaries are more common and without items in there, you can't distinguish are there pairs of items, or individual?
So this also means create dictionaries.
We could also create them populated like this.
Using keyword arguments, so dict Bill equals two Zoey equals 7, Michael equals 4.
That's the exactly the same in terms of the outcome as writing what we have right here, so same idea.
If we want to get one of the elements out, like if we want to know the value that Zoey has, then maybe we have a variable, right now it has a value Zoey.
So we could print wins by name, so Zoey R, whatever the value comes out.
So D bracket, that key, you're going to pull out that value.
The key is Zoey.
The value is 7.
So it's going to print, wins by Zoey R 7.
Maybe some capitalization and punctuation as usual going on here, but, you know this is what the code does.
We also saw that if you say d bracket a key, and the key is not in the dictionary, it doesn't just not give you something back, it crashes.
So you might not want that.
You might want to use this safer version of .get and then pass the name.
So dot get name, give us wins, if there's wins, we can print there are seven wins.
Otherwise, we can say this player's never played a game with us.
Okay, so that's a useful way, if you're unsure if data is in the dictionary.
These are super powerful.
It takes a little while to get your mind around them.
But once you do, they're really, really great to work with.
|
|
show
|
4:17 |
Now it's time to work on our rock paper scissor game.
We're going to do a couple of things we're going to start out by taking the rules that are encoded into the if else statement and encode them into a dictionary.
So again, we have the old game the game without these data structures there and I made a copy so that we can start you know you can have the old version and the new version for your records.
So lets open that.
And then here, and run this just to make sure it's still working, it says oh we don't know where the interpreter is lets go grab one.
That'll work, okay.
What are we going to roll?
We're going to roll rock.
I guess, lets try that again.
We're going to roll one, which is rock and now I roll two which is paper three which is scissors and as I keep throwing scissors computers, computers on to us it knows I still am yet to win one of these rounds.
But none the less here's our game.
And let me show you a cool little trick.
I'm going to go over here and do a refactor, rename on the project, call this RPS structures.
There we go, it didn't change the file but then if were back here in our most recently used files you can see that's our old, that's our old one and this is our new one.
Okay that might help.
Also lets give this a proper name here.
And do something like this.
Put this in like that.
So we know what we're working with.
Okay great how's it looking?
Yeah, looks great.
So lets look at this again.
Down here, remember this beast?
Make this full screen and give us a little room to work with it, so what we're going to do is we're going to say if there's a tie it's one thing, but then we've got to start going okay if it's rock, what defeats rock?
Well, paper defeats rock, so the other player wins.
But what is a losing play against this, against the rock?
Well, scissors is a losing play so the person who threw rock won.
All right so lets just take this bit up here and I'm going to put this to the top.
Could put it inside this function but that means every time you call it we're going to compute this data structure.
Not terribly expensive but, you know it really doesn't change so lets put it up here like this I'll call it rolls like that and lets just put, inside you can put what's called a literal string here like this just so we have it for a minute.
So it doesn't mess up our formatting and what not.
But we're going to have a couple of keys, have that.
That's going to have the value of none.
That's fine.
You got to put a comma.
We're going to have one for paper.
And we're going to have one for scissors.
So the idea is we're going to go to this rolls thing and we're going to ask, Hey I have paper somebody rolled paper, I need to compare it to another play.
So we could have none, we could have seven we could have whatever but I also showed you that we can have other dictionaries that are in here.
And this dictionary is going to contain two things defeats, with none for the moment, and defeated by.
So what we're going to do is we're going to write down what defeats rock, well what defeats rock paper defeats rock.
At the moment we have one as you'll see we could have many, many things there.
And actually lets put this as a set lets put it as a list, honestly sets probably better but where we're going you're going to see that lists going to work slightly better.
Cause like I said there could also be sponge there could be other things that go in here but for now there's just one.
What is defeated by rock, well scissors are defeat by rock.
Okay so that's the thing that we put for rock we're going to go get rock if that's what they've thrown and then we could be able to ask, This other throw is it in the defeats, this other throw is it defeated by?
And that'll help us answer the question.
And these are going to be exactly the same shape but not the same values so paper defeats rock and paper is defeated by scissors.
This one is not right.
I have this backwards hold on.
Paper, scissors.
Rock beats scissors, rock is defeated by paper, okay.
Paper defeats rock, but paper is defeated by scissors, okay.
One more time.
Got to do the same thing down here.
What defeats, what does scissors defeat.
Paper.
And it's defeated by rock.
Okay so we have this data structure here now might be wondering well, okay cool, that's nice Michael but what does that actually get us?
It gets us two things it gets us a much simpler way to check whether or not we've won.
I'll show you that in a second but it also gets us the ability to add incredibly easy like if we want sponge we just do one more line here, sponge.
We won't even have to rewrite the code that checked for the winner.
Just, this data structure will store that.
|
|
show
|
5:24 |
So this down here is going to be a little bit different.
What we need to do is we want to get just the keys not the values.
So we can come over here and say this is going to be a list of rolls .keys with roll names.
Come here and say keys.
That's just the first levels.
So it's, you know, rock, paper, scissors not their values.
And then we want to turn that into a list.
So we're going to go down here and say get the rolls for that person get the rolls for that person.
Great, now here's that check for winner thing gets interesting down here.
Now remember all of this.
Woop, tough battle winner well if they tie ya know what they still tie.
It's totally true.
So what else can we do?
We come here and say let's say, outcome equals what are the rolls I'll get the value from roll one.
So here's the thing player_1 plays roll one and so far we've been playing everything from the perspective of that player.
So what we are going to do is we're going to come down here and we're going to try to decide does this roll that the player_2 played does it defeat roll one or not.
Let's just do a little print out here.
I'll do a little f-string so we'll say roll one gives us some value down here.
This outcome.
Just so you can see what's happening.
Now we are going to run this and I'll say If I play rock, what are we going to get?
This is the value that comes out.
So we said rock and these are the outcomes for rock.
If the other person plays scissors or anything that's in this list on this part it defeats those things.
But if anything that the other person played is in this list it's defeated by.
What we can do is we can say really simply if roll two in outcome .get lets be sure we got the right value on defeats.
Okay, if it's in this set that it over here then what happens?
That means we found out what roll it was the thing that the other person played is defeated by roll one.
So we will return player_1 it'll say elif roll two in outcome .get.
Well we want this other part of the value over here with their defeated by fits in this thing.
Return player_2 and let's get rid of this.
It's possible that what we'll get back here is not a value.
And if we remember if you ask for a value that doesn't exist like they played something that's not in our rolls actually for some reason.
This is going to return none when we try to access it.
This way is going to give us an attribute error.
So what we can do is we can simply say you know what just give us an empty set, an empty list here like that.
If it's something they're asking for that doesn't exist just give back a no data actually lets say we're going to need a dictionary there we go.
So we're going to have this.
Now lets go ahead and try this out make this roll names and use that down here.
Alright, We've made some significant changes.
Lets see if things are still hanging together and rerun the program.
Right, we'll play rock and see how this goes.
You play rock, the computer plays scissors what happens?
You takes the round.
Now you win!
Yes!
That's right.
And how did it know?
Because when we played rock it said okay I'm going to go get the rock data.
The key is rock.
Here's the data and then the computer played scissors so it said, is scissors in defeated by like is the rock defeated by.
Well paper is in there but not scissors.
We ask is the thing that the computer played is it in defeats?
Meaning the rock defeats it.
Yes, so we won and that's right.
Now let's play the next round.
Going to play paper this time.
You roll paper, computer rolls paper that didn't test anything.
Do it again.
Man, they love the paper.
Okay.
Here we go.
You rolled paper, computer rolled scissors, so...
I rolled paper and then we checked.
Do we defeat it?
No, it's not in that list.
Is it defeating us?
Yes, so there we go.
Let's try, we'll play some scissors computer rolls scissors it's a tie.
You roll scissors, they roll paper.
Again, we defeat paper.
Imma just keep going with scissors.
Yes!
I finally in this course of one this game amazing amazing.
I throw scissors, computer rolls paper we take the round and the game.
Cool huh?
So this is a really easy way to store the relationships between the three rolls that we can play.
What is defeating each roll and what each one of those rolls defeats.
This might seem like well not that big of a difference I mean yes this definitely better but above we added some complexity right.
But what you'll see is we can actually do even more interesting and powerful stuff with this data structure.
Now that we have it like this instead of just in a bunch of ifL statements.
Also here is kind of a cool feature on PyCharm.
And come over here and say local history, show history and it can show us some of those changes there as well.
But here you can see down here.
What we have now is this and all of this business right here is whatever I replaced.
With just this little tiny bit right there.
So that's pretty awesome and its much easier to just verify once that this thing works.
The other thing that's cool is it's not really explosive in commentarial ways right if we want to add two more things yeah we should add maybe like this and we do have to put them in here.
But it's just not as big of a complexity explosion as if it's all in ifL statements.
Alright, so this is how we're using dictionaries to improve the wind checking in our game.
|
|
show
|
5:40 |
Now let's look at one other thing that we had to do a lot of coordination I guess is the best way to put it in order to keep track of who won the game if somebody's won the game and so on.
You notice we have to know how many rounds there are.
There's how many times has player_1 won how many times has player_2 won and then we have to check it like this and we got to check it like that and then down here, we have an if else statement where we check if the name is this we can increment that number if the name of that one we can increment that number.
Woo, that's not pretty.
So let's go write another function here.
Find a winner.
Now find_winner is going to look for an overall game winner.
So what we're gonnna do is we're going to create a dictionary that keeps track of given someone's name how many times have they won and we're going to have a list of names.
So let's just say return false for a second.
So this whole part up here we'll just be able to say we need something let's just type wins that doesn't exist yet and names we're just going to put a list of player_1 player_2, like that.
We could store this in different way but we can just stick it here this can be okay.
Now wins, let's go and create a dictionary for wins.
And it's going to be player_1 is the value.
Actually, let's write it like this.
I'll show you the not easy way but the easy to understand way but not the clean, pretty way and then I'll show you a better way.
So we can come here and say, like this.
Yeah, I guess we can create like this.
So we say player_1 equals 0 player_2 equals 0.
There's some cool tricks that we can do to make that a little bit nicer but that's okay.
Let's come over here and get rid of this.
Now we're going to pass a wins and the names over and this one could even be better.
This might be something like wins .keys like this, right?
All right, those are going to be player_1, player_2.
So let's go over and do this find winner.
How's this going to work?
Well remember wins as the name and then how many times each one won.
So we'll have how many rounds we want to play and then we're just going to do this for name and names.
How do we know the game is over?
If somebody has won as many times as we're playing the best of.
So how many times has whoever this is player_1, player_2 won?
We'll say if wins, get name that's greater than or equal to best of who won.
Otherwise, if you make it all the way through however many names there are nobody's gotten more than the best of then there's no winner.
Now this might crash potentially.
So we can put a 0 there just in case.
The way we put it together surely they're going to be there but there's going to be, you know a value for that.
But just to be a little bit safe I'll put a 0 so we get a number back that we can still compare against the best of.
Now, that works up here but how does this work down there?
Well check this out.
Here we can just say if there is a winner all we're going to do is go to our wins and find whoever the winner is and then increment their wins by one.
So all that is now replaced with that one line 53 there.
We don't have to check if it's player_1 change players one's variable if it's player_2, change player_2's variable.
No, this data structure, this dictionary holds all of the players and all of their scores so we just have to go find the winner get their score and change it.
Now, down here and we're going to need a little bit of something as well.
This will be player_1 and this will be wins of player_2.
And this part here about the overall winner remember all this, checking here if this or that and so on.
All of this here can be replaced with a very simple overall winner equals we wrote a function, takes the wins and the wins.keys just like that.
Again, this complicated if statement is now replaced with just a simple little dictionary thing instead of having multiple variables and checking and so on all of that now like this.
If we did things right this should work.
And the essential thing that we did here was right there, was using this dictionary to track the wins.
And each time through I'll print out and we'll take this away again but I'll print out current win status I'll print out wins.
All right should work the same none wins the game.
Yeah, I'm going to say no.
Say well there's not a winner I know a little bit backwards didn't I.
Okay, there's not a winner so we got to keep playing.
Available rolls, what is your roll?
I roll rock, computer rolls rock and that means it's a tie, nothing's changed.
Okay, I'm going to roll scissors computer rolls paper, I win.
So here's the current win status.
I guess I got to do it one more time need to show it.
Here's what it should be it's out of order.
I got one, computer has 0 but now again I have two so just not printing it soon enough.
Now if I were to print it one more time and say you three, computer 0.
See how we're using this dictionary to keep track of that?
I'll go ahead and just move this where it should've gone down here and then I'll comment it out.
Okay, so we're able to use these dictionaries these data structures to dramatically simplify the juggling of well there's three players maybe and all these different rolls and if this player plays that roll then we change that variable.
No, we just have these couple of data structures that store it and we're only touching the surface of how awesome this is going to be.
This is going to be way better.
Think mods, think all kinds of cool stuff that we can do going forward.
But for now we're going to leave it here with the same program doing the same thing but much nicer on the inside.
|
|
show
|
1:26 |
We saw that data structures dramatically simplify our code.
Earlier, we had those really complicated checks to juggle all the different things that we were doing.
And our dog, it wasn't happy.
This dog, this is a happy dog this is a dog that loves clean code, I guess.
So, one example was we wanted to track the wins without having player_1 wins and then all the player_2 wins and then if player_1 wins matches this then player_1 value and all this other weirdness.
So we were able to just create a dictionary called Wins and have the name of the players as the keys and the values start out at zero and then we increment them and then, to find the winner, we just say How many rounds are we playing?
3?
go through each name to see if any of them are high enough if they've won, then you'll return that otherwise, nobody's currently won.
And all you got to do to find who's currently won its either no one or one of the two players is pass the win, no wins above, or the player name.
Really really nice way to keep track of linked data together using this data structure.
There's a lot of stuff that we've done with dictionaries.
In this chapter, yeah, they are really really powerful they're probably the second-most important data structure.
First one, of course, is lists.
And we'll talk about those a little bit as well.
But in this case, it was the dictionary that we needed.
How do you know a dictionary?
You going to use a list?
Well, we'll get into that in a minute.
But think this code is dramatically better than what we started with.
|
|
show
|
3:16 |
We've discussed three important data structures that you see all the time in Python.
Dictionaries, lists and sets.
Let's talk about when to use which one that can be really challenging.
So, let's start with our friend, the dictionary the one we've been using the most.
When is it a good idea to use a dictionary?
If you're going to look up an item or value by key.
If I maybe have a user ID and I want to get the user object.
Or I have a player and I want to get their score.
Or I have a role and I want to get a complicated data structure that represents the outcomes when playing against just that role.
So this is really the use case for dictionaries I'm going to look up something up by some kind of value and this lookup is extraordinarily fast.
It basically doesn't matter how large or how many items are in the dictionary it's able to look it up super, super fast.
Dictionaries are not good choices when you need serial access, you want to preserve the order you want to sort them, or you want to access them by index.
Give me the third item in a dictionary is not really a question that you can answer.
Until recently, dictionaries didn't even preserve their order and sorting them also doesn't make sense.
So, that's when you don't use them.
Now, they look like this down the bottom.
We saw there's many ways to create them and work with them and so on, but you print them out they're going to look something like this.
Key:value,key:value.
The other really, really important data structure is the list.
This is good when you have serial access I want to access it one, and then the other, then the other.
I want to preserve the order or I want to access something by position.
Give me the third one of those or I want to have a bunch of items and I want to sort them.
It's bad for basically when you're going to use something like a dictionary, looking up something by key or a special value.
I've got a list of users.
If I want to go through it and find the user with name such and such, I can do that, but it's very slow and the larger the list gets, the slower it's going to be whereas the dictionary doesn't have that problem.
And it looks like this at the bottom.
Square brackets, individual items separated by commas.
The other major one we touched on was sets.
The most important idea of a set is that it is a distinct collection of items without repetition.
It also is really good at set operations.
If I have two sets, I can subtract one from the other and it'll show me just what's in the first one after taking out the duplication from the second one.
It intersects in all sorts of, you know set based operations you might do.
Just like dictionaries it's extremely fast to ask Is this thing in the set?
It's bad for serial access, it's bad for preserving order or sorting or accessing by index.
None of those things can you really do.
Also, not even knowing how many items are there, right?
If I have a set of three things well maybe it started out with five but it had duplications, so it reduced down to three.
So, that's also not so good there.
But it does have its own special uses.
Other data structures you might hear about are trees, linked lists, arrays which are similar to lists, but usually they have the same data type and they can't change shape like lists have more items added after it's created.
And also, graphs.
Graphs are really interesting data structures.
It's unlikely you're going to mess with any of those.
But it is quite likely dictionaries and lists will appear in your day-to-day work.
|
|
show
|
1:14 |
It wouldn't be the end of the chapter if you didn't have some practice exercises, not worth it.
Let's see what I got on deck for you.
Here we are in our GitHub repo if we go over to practices.
CH07 data structure we scroll down and see what we got.
Now, here's the sort of standard introduction we've gone through that a few times I won't it again.
The core concepts I'm throwing out here for you are creating static dictionaries and dynamic dictionaries as you can see here.
We can even use some cool what are called dictionary comprehensions.
We didn't talk about those yet but they're very, very neat and you can play with them.
As well as reading values from a dictionary.
So here's the deal.
What you going to do in this exercise is you're going to create a dictionary Don't care how you do it, you can create it empty and then add items to it.
You can create it as a literal static dictionary.
All sorts of options are on the table here.
But if you create some dictionary and call it D then this code below, you paste that code below it you run it, it should do things like output seven when you ask for sum as your output Rock paper scissors when you ask for roles, none for Sarah, and so on.
So if you can get this output to match then you've created the right dictionary.
Have fun.
|
|
|
1:01:49 |
|
show
|
2:00 |
One of the first realizations you're going to run into when you start programming is you'll have learned some of the language features and some of those techniques.
For example, you'll be able to loop over a list using a for in loop or create a string or do simple math or work with a list those types of things.
And you'll be able to practice those and so on.
But when you sit down to actually write a program that accomplishes something meaningful something useful, it can feel much like Microsoft Word with a blinking cursor and just a white screen staring back at you when it's time to write that term paper or something like that.
It's challenging.
How do you start?
How do you break this up and just get going?
So that's what this chapter is all about.
If you're getting started and you're feeling a little bit stuck or you're not sure which way to go I'm going to give you a bunch of ways to think about the problem ways and techniques to decide what data structures to use or how to break up your code or your ideas into functions or steps and also a few other things as well.
So, in this chapter we're going to build a new game from scratch.
We've had a lot of fun with rock paper scissors and don't worry we're going to come back to it.
We're going to do bunch of more cool things with rock paper scissors.
I don't think it makes sense to do something as a continuation when we talk about problem solving.
No, what we need to is start from absolute scratch from buy new project, blank file what do you do now, here's what you want to build.
So what I'm going to do, I'm going to give you some advice and give you some techniques and then we're just going to go and build a game and we're going to kind of fumble around through the creation of it together and I thought it would be a good place to start and I'll try to leave mistakes if I make any or ideas.
I'll try to talk about why I decided to go one way or another or alternatives and so on.
And, yeah, I think you'll get a lot out of this one.
I've seen something built from scratch and thinking through the problem.
Not going to be hugely complicated because, well we don't want to spend hours and hours on it but it will be complicated enough that it might not be entirely obvious how to do it.
|
|
show
|
5:38 |
Before we get into our new project that we're going to work on, let's talk about some techniques and ideas that'll help you get started when you're trying to solve a problem and you're not sure what to do.
The first thing to ask is have you seen similar problems.
Have you seen solutions to similar problems.
You're not completely new to programming.
You've already made it part way through this course, for example.
Have we worked with data in some way that is similar to this?
Have you been looking around on the internet and seen other ideas and solutions that are maybe out there, or other tutorials?
Have you worked on something like this before?
This is really, really helpful because you can compare what that problem and solution is to what you need to do and see how they're the same and different.
And when they're the same they can give you some guidance on what to do.
Visualizing the data is really helpful, as well.
It's one thing to say well, I have, I don't know this data and some file and it's kind of hard to conceptualize or whatever.
But if you can see it, and maybe this is loading into Excel, this is maybe this is seeing the data in a debugger or something like that.
If you can see the data, you could even just print it out and see what comes out.
If you can see the data that can help you think about how you need to interact with it.
So this is an important role, an important step in here.
Divide and conquer: you've probably heard this one before for problem solving but it's really, really important.
Imagine you're writing a commerce site you might be working on the part of the problem where it's, like, let the user buy something.
Okay, well that sounds really complicated so what's involved with that?
Well, you've got to charge their credit card you got to verify some stuff you got to get their shipping information and then you got to send out an e-mail receipt.
You've got to actually have the stuff sent to them.
Whew, that's a lot to think about all going on there.
But break it into smaller pieces.
One of the steps there is, send them an e-mail.
Okay, well, think about how to send an e-mail.
And you can research that really clearly.
One of the steps is getting their shipping address.
Well, how might you get their street, their city their state, and so on, from them?
Well, that's not too intimidating likely.
So, breaking it down into these steps these high-level steps, and then trying to attack them one at a time, and maybe even breaking those into further, smaller steps is super, super helpful.
Run through the data structures.
We saw using the right data structure in our rock-paper-scissors game simplified the code dramatically.
It let us think about an even more generalized problem, actually simpler than our small simple case.
Remember we switched out, like, the rules of the game from if, else statements down into a simple dictionary.
And in that chapter, we talked about the different kinds of data structures that are very, very common: lists, sets, dictionaries and then, even some of the other ones.
But just thinking through when you're at a lower level of this divide and conquer stuff how do you store the data and interact with it in the right data structure?
That can make a huge difference.
Another one, which we haven't touched on yet because we're just focused on getting the basics of Python working, is the external package ecosystem in Python.
So the place that you go and get these packages is called PyPI, or the Python Packaging Index.
And it's at pypi.org.
Over there, there's 215,000 libraries meant to solve certain problems.
So, if you're trying to do something like some complex step, like, let's say, send an e-mail there's a ton of libraries over there built for sending e-mail.
If you're doing something with physics instead of doing all the Python code to actually do some complex physics calculation there's probably a library, just say do that calculation, and it just does it.
So if you can solve the problem by having someone else solve it for you and by that I mean using a library that already solves that problem that is a really good option.
So be sure to check that out.
Sometimes it's daunting to see so many different libraries and know which one you want so check out awesomePython.com.
They have sort of a ranking of the popular ones categorized by the different types of areas you're working.
Also, just realize this is part of the journey.
It may feel like, well I'm stuck because I'm a beginner, I'm stuck because I'm not good at programming, I'm stuck because, whatever.
No, everyone goes through this.
Everyone who works on creating software has to go through these steps of the blank page with a cursor just looking at them and some problem to solve.
You get better, quicker at running through these different techniques, but you got to realize that it's part of the journey and just take it for what it is, and enjoy it.
Some parts will be frustrating but then when you solve them it'll be really, really satisfying.
So part of the journey.
And finally, just start.
Sounds simple, a lot of people have problems with this.
It's easy to sit around and think, and think, and think and plan, and compare, and think about trade-offs and what not, when you're trying to solve these problems.
Maybe I should do it this way maybe I should do it that way.
Oh, what about this?
It can get really overwhelming and you can just get stuck in what's called analysis paralysis.
That's just trying to analyze the problem and never actually getting started.
Here's the thing about software: you write it one way, if you don't like it that way you change it.
You have data one way, you don't like it you convert it to another structure or format data structure, whatever.
As you get started, as you make progress you realize what the detailed steps are what mistakes you made, go back and change them.
So just start, and once you've got an idea just run with it.
If it's not the best idea, back track a little and then you can change it.
Nothing's set in stone.
It's just words and characters on a screen, right?
So here are a handful of techniques to help you solve some of the problems that you might run into to create the software that you're trying to create as a software developer.
|
|
show
|
1:18 |
What problem are we going to solve in this chapter?
We're going to write tic-tac toe.
Now that might sound pretty simple, right we've written rock paper scissors so how different is tic tac toe?
Turns out it's fairly different and I would say it's at another level of difficulty.
Why is that?
Cause it seems pretty straight forward right?
Kids play tic tac toe all the time.
The challenges you run into are around the data structures.
Holding this tic tac toe board together there's a bunch of different ways in which we can do that and when you're getting started that can be challenging.
The other place where I can see it might not be entirely clear is checking to see if somebody has won a game.
Cause you got to check across you got to check down, you got to check a diagonals and depending on the data structures you've chosen those may be super easy to come up with or they may be really hard to come up with.
So those are the two main challenges I kind of foresee for us.
And the reason I've chosen tic tac toe it's not terribly hard.
You understand how to play the game I'm sure if not just Google tic tac toe.
But it does have this other level of difficulty and we haven't addressed it yet.
We haven't done anything with tic tac toe.
So I think this is going to be a fun place to think through the problem solving and think about the trade offs and ways that we can do things better as we write this program.
|
|
show
|
3:44 |
It's time to get started working on our tic-tac-toe game.
More over here in our Github repository And then in CH08 tic-tac-toe is empty so we are going to drop this over into PyCharm Community Edition and get started with an empty project.
So, we are going to need a Python file let's go over here and create a call it game or something like that.
Now, I'd like to go ahead and just run it right away.
That way afterwards it looks like we got to select the Python interpreter.
That way we can just click right here every time or just hit Control R.
Well, here we are in that situation I described.
Blank file, blinking cursor, now what?
Let's start by just thinking about what it is that we need to do to create this game?
What are the major steps of tic-tac-toe?
Well, remember just imagine you're a kid sitting down at a table in a restaurant and you're waiting for the food to come and you're bored and you say Hey, lets play tic-tac-toe.
What do you do?
Well, first thing you do is you get a piece of paper and you write out the board.
You write two vertical lines two horizontal lines intersected.
So, the first thing we got to do is create the board.
This is going to help us think about the data structures how we want to store that information and so on.
We might want to validate the board is okay maybe it's fine.
We could choose an initial player.
That happens all of the time, right?
Who gets to go first?
And, are you going to be X's or are you going to be O's and so on.
Then what you do is you go around and you start whoever's turn it is they put their symbol into the spot on the board.
And they do that over and over switching sides until somebody wins.
So, let's say until someone wins maybe we can indicate that with a little indentation or something like.
Choose the location, if there is one, mark it.
We are going to toggle the active player.
First, it's your turn, then it's my turn.
Then, it's your turn, then it's my turn.
Until somebody wins and then it's game over.
Alright, so this is actually a pretty good set of steps here for us.
Instead of thinking about how am I going to write tic-tac-toe?
How am I going to do all of the stuff?
All I have to do first is think about how are we going to create the board?
Things like that, I guess, maybe in here somewhere until someone wins.
We want to, this is going to be check for a winner or something like that.
We're going to need to maybe think a little bit about how we're going to check for a winner.
Depending on how we create the board.
Choosing an initial player this one should be pretty easy.
We are going to have two players, just pick one.
This until number while loops.
While a condition is true until someone wins that's awhile loops.
You're just going to awhile there is no winner.
And then we have to get input from the user.
Where you're going to pick?
Maybe show them the board?
That's not the way it works in the real world.
Because it's always physically there but in this maybe we will want to show the board as part of the choosing.
Here's the current board, what location do you want to get?
Mark it, we also have to make sure that they don't pick a pre-played spot.
You know if they say, I want to play the middle.
And there's already somebody who's chosen that perfect middle spot to start from.
They can't do that, right?
So, we're going to have to do a little verification there.
And then that's their round, their round is over.
It's the other player's turn.
And then we're going to show that other player the board.
Ask them for a location and so on.
Somebody wins, guess what?
The active player won.
This is what we got to do.
Instead of trying to think of how, geez we got to do all of this stuff.
How do we create the board?
That's it, that's all you have to think about and solve.
And then the next one is how do we choose an initial player and indicate the players?
This what I was thinking about is trying to divide and conquer this problem.
This where we are going to start from.
|
|
show
|
7:07 |
It's time to create the board but real quick before we do, let's just create a little bit of a function that we're going to be able to run here, like this.
I always like to put my code inside functions even to help us organize it because maybe you want to break them out later and that turns out to be easier to do if you have a higher level organizing function.
So, here we go board equals, well what?
What are we going to put here for the board?
This brings us back to another one of my pieces of advice, is to think about data structures.
How might we store this information in here?
And, it really comes down to how we want to think about the board, one way let's think more about how we're going to use the board.
Let's say it's none for a second.
What we could do is we could say well how do we want to get this information back?
We could go to the board and we can get thing at one comma two or something like that.
We could maybe go over here and say we want a first row and then for the row, we'll have the columns.
There's other ways to store it, I'm sure but we got to think about how we're going to do this.
Now this side, over here, this bit this probably is something like a dictionary.
We could have a bunch of different keys.
We could define a dictionary like this.
We could say board is this and that zero comma zero position.
Well, if you wanted you could have 1, 1 if you prefer that way of thinking about it or you could have nothing for the moment.
And then, go across, maybe let's say that this is the row this is the column, go across the top, end like that.
And, we're going to have 1, 0.
2, 0.
This is okay, but there's a couple of challenges here.
I can't easily ask how many items are in a given row or in a given column.
That turns out to be something that's tricky to do.
This would work but also these strings there's really weird situations like if there's a space here, then that's not the same as not having a space.
I mean to humans it looks the same but to computers, it's like, I have the string zero comma space zero, that's not the same as the string zero comma zero, alright?
So, it's not quite probably the best data structure.
So, that was a possibility.
I'm going to say no for that one which means that this use case here doesn't make a lot of sense.
So, what about this one, if we come over here and say give me the first row and then from the row, we can get the first column element cell one, cell two, cell three.
Remember you always count at zero so it's off by one for humans.
So, to me this is a little bit nicer because then I can just ask for the first row and say well, how many items are in the row?
Or how many rows are there at all?
How many columns, how many rows at all?
It's a little more discoverable.
So if we want to put stuff in order like that so we can have the first row second row, third row going down.
That turns out to be a list.
We want something ordered, we can access it by index and we go back to those data structures.
In that world, maybe a typical board would look like this.
It would have a list of row 1, row 2, row 3.
Yeah, well what is a row but a column of three columns basically or three cells.
We know how to say three cells.
We can access in order by index.
Well, that's cell 1, cell 2, cell 3.
What we have is a list but instead of having scalar items like numbers or strings in there each element in the outer list the list of rows is going to be a list of cells.
See down here, this will be like row 2 column 1, it's not great.
Just do an underscore.
That's the first item then row 2, cell 2.
Row 2, cell 3.
And down here, same thing but it's going to be row 3.
Cell 1, cell 2, cell 3.
Does that make sense?
This is one option.
This is also an option.
There are others still, we could just have a straight list of cell 1, cell 2, cell 3, cell 4 cell 5, cell 6, cell 7, cell 8, cell 9 and then just do the math to figure out if you want row 2, column 2, that's the fifth thing in the list.
I really don't like that one.
I like either of these better than that, I think.
Yeah, so what we're going to go with.
This is what I've come up with.
This looks like Tic Tac Toe, like if we put in numbers here, let me comma this out for a sec.
Make a copy.
Let's just put in, X, X, O X, blank, O X, O, blank.
That looks like a Tic Tac Toe board, doesn't it?
So to me, I like this structure best.
This one works but it doesn't look like Tic Tac Toe.
The one where it's like nine in a row also works but doesn't look like Tic Tac Toe.
This one looks like Tic Tac Toe and it lets us really easily answer questions like how many rows are there.
Well, that's the len of board.
That's how many rows.
If you want to know how many columns there are you just go to any row and you ask how long that is.
If you want to get something in row 2, cell 3 and where everything's off by zero so you would say one, two like that.
That's how you get it.
So it's really easy to get over there to those items.
I think this data structure of a list containing a list of rows where each row is a list of cells I think that that's what we're going to go with, okay?
So we're going to comma that out again for a minute.
Leave this here for a sec.
Let's go ahead and fill this out.
Now, what we need is we need the board to start out empty.
So there's a couple of things we could do.
Remember none is the programming way of saying empty.
What we'll do is we're going to say there's a board it has three rows like this but we got to put three things in here as well.
Now I could just do this.
This would be totally good.
Like this and do like that.
When we print out the board, I'll have to see.
It'll show up none, none, none unless we do something to replace none with a different character.
I think actually, I'm going to go with this.
We're going to have a little function that'll say show the board or some idea of showing the board and it's just going to say is there going to be an X?
Is there going to be an O?
Or if it's none, we'll just put something like a little underscore so that there's spaces a little character.
But it needs to start out with no plays so this is what we're going to use for our board.
I'm going to put like, this is NVA.
Board is a list of rows.
Rows are a list of cells.
This is a data structure I'm going to start from and you're going to see over and over again.
It makes it really easy to play Tic Tac Toe once we know how to record the entries for each player.
|
|
show
|
3:38 |
Our next step in our divide and conquer is to choose the initial player but in fact we don't even define the players yet so we're going to need to figure out how we represent the players and then choose one of them, okay.
So it's kind of uncovered something that we didn't lay out, is decide who the players are.
I guess that's, that maybe in the traditional sense happens up here.
Right, this is when you're sitting at the table, you say Hey, let's play tic-tac-toe that means the players are me and whoever I'm addressing so, well we're going to put it in a different order just so we can have our board up here.
Now, this stuff, I've already committed this to GitHub so if you want to go and have it to look at you just go and look at the history or this file here, and it'll be there but just to keep us sane I'm going to remove that.
Now the next thing we need to do is have the players so we could have it like we had in rock, paper, scissors We had you and I suppose two it says computer, something like that but you'll remember this resulted in a lot of challenging things.
We then had to have number of wins for player_1 number of wins for player_2 who is the player, right there was a lot of stuff that we had to keep kind of lined up so it turns out that we can go back to our data structures again and think about this in a more general sense.
Often in programming it's easier to solve the problem in general than it is for one of these specific cases, like here.
So if we just have the players, and we say There's something that has all the players in it.
It's easier the coordinating a bunch of variables as we'll see.
So let's go over here, and we'll put this into a list.
Honestly, it doesn't matter if it's a list if it's dictionary, or whatever but it will be a little bit easier for us to figure out who the active player is if it's a list.
The reason is, we can address these by position.
Zero, one, zero, one, zero, one.
So if that's the case we can come over and say active player.
Now you could say active player but let's put active player index is going to be zero.
That means we can go over here to players and say active player index and it's going to print out whoever that is.
It could be zero.
And when it's time to switch all we have to do is make that a one and now the player is the computer.
Put it back to zero, and now it's back to us.
We could also use our modulo thing, remember that?
We talked about that in one of the previous chapters the division.
So we could do something like this.
This is going to be equal to that plus one mod number of players, okay?
So this is going to go from zero to one, one to two but two is divided by, and that gives us zero again so it just is a way to toggle that.
So that's kind of nice.
I'm not sure it's super important here but if you had like 20 players or something you can cycle through them super easily doing that.
Okay, so here are our players.
And one other thing we're going to need to keep track of that might be worthwhile, we'll improve on this as we go but, player symbols.
So what do you want to be?
Xs or Os?
I'm a fan of X.
I'm typing, so X it is.
O goes there.
So these are going to be the symbols that player_1 and player_2 play.
Well, that's it.
I think that's all we had to do to, you know choose the players, well, you and computer and then choose an initial player so we'll just have active player index that means that's zero so that's the first element in the list.
Again, these all start zero, one, two, three not one, two, three, four, as people count.
So that means we are the initial player.
Might as well stack the odds in favor of us against the computer, huh?
|
|
show
|
2:46 |
The next thing we need to do, that's not checked off is we have to go and play until someone wins.
So, notice I put some comments in here create the board, choose initial player.
I wanted to put that in there to kind of highlight what problem solving bit we were doing.
Also, I've decided to just call this symbols.
I don't want that to be super, super long until we work with it.
So here we're going to being doing until Well, how do we do that?
Remember, I said at the beginning that until a condition is True or False that's going to be a while loop and what we have to do is put some kind of test in here like check or find winner.
What we want to do is actually go and look through this board and see if there's somebody that has X, X, X or O, O, O or more tricky X, X, X and things like that.
We're not going to do that yet, but because that's complicated let's write a function and pass the board over there and maybe we need to pass some more information.
For now, I think we're just going to pass the board and we'll say yeah, there's a winner or something like that, but it could be that we want to pass this over so it can say you know, you are the winner or computer's the winner.
We'll have another way to keep track of that actually.
So, we're going to find a winner.
Now, notice, this has got red curlies.
That means find winner doesn't exist yet but it will, it will and then we're just going to go play a round a round like this.
So we've got to go and create this function.
Remember, your function stuff from earlier we can go and type def, this, and do the bits or we could just hit alt, enter in PyCharm and say create the function.
Don't really like that it puts it at the top but it's the safest thing it can do but it's because the way main works it's not necessarily you want main to be the top.
Okay, so let's just for now return false.
We are going to take a while to figure out who the winner is.
This is going to be a really elegant solution but it's going to take a little bit of thinking through so let's not worry about that now.
We're not at that step yet but it definitely has uncovered the need for us to be able to, given a board and how it's been played determine, has anybody won this just yet.
Before we worry about the winners let's figure out how we might just play a round.
Now, let's go ahead and run it and have a little bit of fun, see what happens.
Ah, yes, so I had that backwards.
It's going to do this as long as it finds a winner.
No, you play the game as long as there's not finding a winner.
There we go.
Play a round, play a round oh my gosh, it's an infinite loop, stop.
There we go, stop, stop, stop.
Well, that part works.
We're doing it over and over as you saw and we're checking for a winner.
Right now we can have a to do implement how we check for a winner.
|
|
show
|
5:11 |
What's next in our list, here?
Show the board.
Alright, well, we haven't quite done check for winner but I'm going to give that a check mark Nonetheless.
Alright, so down here, instead of just saying play around let's do a little bit more.
I'll go ahead and put the comment show the board.
We need a few more things here, though.
Print.
We can say somethin' about who's turn it is.
Let's just go like this and say player equals remember players of active player index.
We'll worry about toggling that in a second.
But let's say it's player.
Here's the board.
Let's do a little print.
Going to do a print before that as well to give it some space and then we want to just say show board.
Now, we could do this right here but it turns out that maybe we want to show the board here and then the final board when the game is over.
It also turns out to be kind of messy, some of these things so if we do it here it's going to make it really hard to just read what this loop is doing.
In fact, we could probably do a little bit better as well if we go down here and say def announce_turn or something like that and we could say player put announce turn, pass in the player and put this down here as well.
Basically it'll read much more like English, right?
Announce the turn, show the board, get the input, so on.
Let's go down here and find another function.
Notice how I'm using functions here to kind of bring some of this to life, right?
We have a function called show_board.
We have a function called check for winner.
We're going to have one that lets them choose the location and so on.
So, let's go and see what we can do with this board here.
There's a couple of tricks.
I'm going to try a couple of angles here.
So, we have the board.
Remember, the board is a list of rows.
We want to go through each row and show its cell.
So, that's really easy.
We just say for row in board, and what are in cells or cell in each row.
Well, we could just print out cell.
Now, this is not going to do what we want but let's just run it and see what happens and I'm just going to do an input here so we can take a little break.
Run it and here's what we've got.
It's you's turn.
I'm going to put my name in here.
You can change your name in the real version.
It's Michael's turn.
Here's the board.
None, None, None, None, None, None, None.
Yeah, that doesn't look like a board, does it?
So, let's see.
Let's do a little bit better.
Well, the problem here is that these are all going vertically and we want them to go horizontally.
So, what we can do is we can go and say the end is actually equally to; this is close, but not quite what we want.
Put it like this.
Now they're all across, okay.
Maybe better.
What we need to do is say after each row we want to print out we want to actually have a new line, so let's try that.
There we go.
None, None, None, None.
Okay, pretty good, pretty good.
Let's do one more thing.
Maybe we want those columns in there before we say print like this.
Maybe give it a space and say and is nothing.
We do it like that, nope.
Alright, we want that at the beginning of a row up here.
There we go.
That looks a little bit like tic-tac-toe.
However, None is not generally what we would expect to see so let's go over here and we'll say this; we'll say symbol equals, and we can do an if statement.
We can say if cell is None, then symbol is something else, symbol equals cell.
Let's put an underscore, like that and then we're going to print out symbol, all right?
There we go, that looks like more of an empty board doesn't it?
And we have Xs in there, what's it going to look like?
About like that, okay.
I think that's going to look good but notice this is a lot of junk to come up with that.
Now, Python has a way to condense these if statements into one line, and when you have stuff like this actually it turns out to be really valuable.
So, watch this; I can say symbol is equal to cell if cell is not None else this.
So, the stuff below is the same as the stuff above.
Yes.
So, what it says is the cell is going to be an X, an O, or None so if it's an X or O, so that means it's not None we're going to show that.
Otherwise, if it is None, we're going to show this.
Cool, huh?
Called a ternary expression.
Same output, all right?
But if for some reason over here we were to hack on cell and say it was an A, now we get a bunch of As.
All right, looks like that is working.
This is showing the board.
I think that's decent.
I'm going to call this show the board step done.
|
|
show
|
5:44 |
Show the board.
It's got its check mark, it's done.
The next thing to do is let the active player choose a location and so, down here, we're going to something like choose location or play or something like that.
And what do we need to pass in?
Well, it's definitely going to need the board because we need to know what locations are available.
Does it need to know the player?
Probably not, but it does need to know the symbol 'cause when you pick a location it has to put an X or an O into that location so let's come over here and say symbol is going to be symbols of active player index.
Remember, Michael has X, computer has O's so we're going to pass the symbol to be played here.
Probably is good, but let's say let's do a quick test because what can happen here is I could try to play a space that computer's already played or even that I've already played so we'll say if not, we can do something like print that isn't an option.
Try again.
And there's a really cool flow here for this to work.
We can just go back and say you know what, just run through this again.
Say it's Michael's turn again, show them the board and we can do that by just using the continue.
Remember, continue just ignores all the stuff below and then, goes back the loop.
We didn't do anything.
It should still be in a winner.
The player didn't change so it should still be the same players.
The board didn't change.
It's still the same board, so this is a really nice way for us to try again if they get it wrong and you know they're going to get it wrong, right?
We have definition of our choose location.
All right, we're going to have a couple of options here.
Let's say we'll start like this.
We'll say row equals input, choose which row and now, remember this is going to come back as a text but we want it to be an integer and column.
Column, all right, so that's going to be the row and the column, so the cell that they want to play is going to be board of row of column, right?
Almost, almost, they might not choose the right value here.
They might put 7.
It can't play row 7, but more likely they do choose the right one but they choose one, one, meaning the top left and that's actually the middle, right?
Because Python, in the programming languages are zero-based.
Humans are one-based.
Those do a couple things.
Here, we'll say row -= 1 column -= 1.
Then, we can test.
We can say if zero row is less than zero or row is greater than or equal to, let's say greater than 2 and we could actually do, yeah, this is fine.
If it's greater than 2, we're going to return false same thing for column.
Now, maybe you wanted to generalize this a little bit more so you could have larger boards like a five by five.
I wouldn't want to play that but we could do this by saying this is less than or equal to the length of the board.
So that would be the number of rows, remember?
Row, row, row is in the board and this could be the length of the board of zero the number of cells in the first one and that's got to be equal area.
Okay, but if that's all okay, we now get the cell.
They should be able to play this position if it's not empty, so we say if cell is not none.
Let's just say if it, yeah, if it's not none that means there's already this thing there.
We're going to return false.
You can't play because it's already been played.
All of that, we've done the conversions.
We've done the checks that the numbers are okay.
We've gotten the cell.
We verified the cell is not already played.
Well, now, it easy.
We just say that has the symbol in it, return true.
Everything worked out great for us.
Alright, well, we should be able to go and play this here.
Give it a shot.
All right, it's Michael's turn.
By the way, it's always my turn 'cause we haven't gotten to the change your stuff here so I want to play row 1 and column 2.
That should be that position right there and it should put an X 'cause that's my symbol.
Boom, look that, how awesome.
Guess what?
This is going to be an easy one to win.
It's my turn; row 1, column 3, row 2.
Two, that's in the middle and let's do row 2, column 1.
Boom, I won by the diagonal.
That computer's got nothing on me.
It's cool, right?
Very, very cool how this is building up and I think it's pretty straightforward.
Why is it so easy to make this work?
'Cause we chose the right data structure.
It's hugely important to have the right one.
Now, remember I said just get started.
That doesn't mean we couldn't have made the other one to work, but if you're going through them and finding challenges you're like Well, maybe there's a better way.
You're also going to see in this next step that these data structures turned out to be really important as well.
Alright, well, I'm going to give this a little mark there.
Actually, we've got one more thing to test.
Don't forget to test your error handling, so one, one and let's put seven, seven.
That isn't an option, try again.
Or if I say one, one again still shouldn't be an option, right?
That isn't an option, try again.
And now, how 'about one, two.
Done, nailed it.
You can't see it swapping players, but that'll happen soon.
All right, even our little bit of error handling we put down here in choose location is all done.
Hopefully, you can feel how this is working, right?
We've got functions that are almost the name of the initial steps that we had.
I guess I could go ahead.
I could put choose location.
Do you know what?
These are already doing that for us, right?
So we don't really need to.
|
|
show
|
2:43 |
Here we are on our next step in our breakdown that we had here.
Toggle active player.
And because we chose such a cool way of representing this.
I think this might actually be the easiest thing we do yet.
So we're going to come down here.
And again if you don't make it past choosing a location you don't get to play.
But here we're going to go and we want to toggle the active player.
So there's going to be a little bit of a catch we got to be careful with here.
But save the player.
Active player index.
We could just say += 1.
But remember that that is actually going to overrun this really quick.
I go 0 then 1.
And boom, it's going to crash when we try to get the thing 2.
And thing 2 doesn't exist.
You want to use our modulo trick here.
And say it's that + 1.
And we could just go and say, % 2.
because we know there's two players.
But for some reason you wanted to be more general we have these players.
And the real constraint here is that it has to fit within the number of items here.
So we could actually go by the length of players.
That way if there's three it goes 0, 1, 2, 0, 1, 2 If there's 5, it goes 0, 1, 2, 3, 4.
And then wraps.
But right now I'll just go 0, 1, 0, 1.
The remainder of dividing by 2 is either 0 or 1.
Alright, let's just see that this works.
And I'll put my toggle active player.
Here, 1, 1.
It's computer's turn.
What does computer play?
They play 1, 2.
Oh yeah.
Michael's turn.
1, 3.
Computer's going to go for the ever so awesome 2, 2.
Look at that.
Toggle player.
Told you is wasn't bad.
Works really well.
The challenge is we're going to want to go along here and be able to print out who won the game.
Yeah I guess that we can do this.
If we just did one little trick up here.
Like this.
We just list out who the current player is.
And then we always swap it right here.
We'll be able to just print this out.
Because this won't reset the player until it makes it back through the loop.
Which won't happen if there is a winner.
Okay, I think that's what we're going to do.
But when I said there was a little catch.
This is going to flip it to the next player.
And then if there is a winner.
We're going to exit out.
And somehow we need to report that.
So, let's go ahead and print the end of the game here.
Game over.
Player has won.
With the board.
Like this.
And here we can show the board again.
Remember I told you if we wrote it out here.
That would not let us reuse it.
So what we want to do is show it every round.
And when the game is over also show it here.
Pretty cool.
So I think this toggle active player thing.
Working great.
|
|
show
|
9:35 |
Our tic-tac-toe is almost done we just have to figure out how to find a winner.
Again, this comes back to our data structure which is really, really helpful in putting this together.
So let's sort of sketch this out here.
We're going to do win by rows win by columns, and win by diagonals.
Now, what I'm going to do is I'm going to write this in the most straight forward immediate, obvious way I can think of it solving these three problems.
But what we're going to find out, is that this is actually not the best way to do it.
There's sort of a couple of things we're going to have to do that will make this a lot better.
So let's first write out what the rows are.
Well, the rows, we want this as a list or a sequence we can go through that's exactly what the board is though the board is going to be the rows like row 1, row 2, row 3 that's what the board holds.
The cells, or the columns, rather this is going to take some work.
So what we need to do let's just go through them as numbers.
It's going to be easier that way.
So if we say for col how do we go through just numbers?
We could use a while loop but there's a cool thing we can do called range.
And if we go here we can say start = 0 and then not sure it's actually going to not stop at the right spot so we can go click on this and get the quick documentation.
So it returns an object that produces a sequence of integers from start inclusive to stop exclusive.
So that's a little annoying you got to remember to put a 3 here so it goes 0, 1, 2.
Do we call them 0, column 1 and column 2.
And then what is one of the columns let's call index, so we're going to create a column it's going to be a list and what goes into this list?
Just like each row is a list we want to list here.
So the way we're going to get it is we're going to go row 0, row 1, row 2 so like this, this is close not quite done, but two and then for highest middle, bottom and then here we need to know which column are we in.
Are we in the first column which means it's always like 0 no column index here and here, and here.
Is it always the first one in row 1, 2, and 3?
Is it the second one in row, 2, or 3, and so on?
Okay, so that's going to do that.
And then the diagonals the diagonals are a little bit funky as well.
This is going to be an empty list and there's just going to be, well actually, let's not make it empty we'll just do it like this.
This is going to be board of 0, 0 with a forward that's called a forward diagonal.
And then 1, 1, and 2, 2.
Well, that one's easy but now we got to switch it.
So let's go from the front row it's going to be the end coming backwards and then here like this.
Yeah, that should do it.
For all of these we're going to have to go through and then loop over them and see if there's a winner.
Now, how do we know there's a winner?
There's a winner if it's the same symbol across the board, right.
If there's a row of X, X, X or if there's a column of O, O, O or there's a diagonal of O, O, O, or X, X, X.
Alright, so that's going to be a little bit tricky here.
And what we need to do is loop over all of these ideas.
So just do it here for the win by row first.
Let's say we're looking for four each or row in rows what we need to know is what symbol is in the first place if there's a symbol in the first place at all.
So we'll say symbol one, I guess we'll call this, I'll say, row of 0.
It's going to be the first cell in there.
Now, there's a couple of things we can do we can say, if not symbol right, so that means there's nothing here, right we don't want to win because it's None, None, None 'cause then we'll just say continue.
I'm going to make this nicer in a second but if it's all that then we can say four cell in row we're going to go across we'll say, if not cell cell not equal to see how you're saying not equal to, symbol one.
So if there's some other symbol including potentially none, then we're going to continue.
And here we're going to say return True.
Now, that is a mess.
Let's go down to the bottom and say, yeah, it still says returns False.
We can do a lot better and I'll show you here in just a second.
But this is the most naive way of writing this.
Go through each row and we're going to see if it's a winner.
Now, the first symbol got to make sure it's something, not nothing and that's what this test is and then we go through every cell and just make sure that they're all the same.
If there's any that are not the same one was an X, another is a None then we don't carry on down here and we keep going.
Whoo, okay, let's run it for the moment and just see that we can win across the board.
So I'm going to play one-one nobody's won yet, the game's not oh, Michael has won the game.
Actually that would be wrong.
All right, rather than figuring this out let me just rewrite this in the way that I wanted to write it in the first place.
So what we're going to do over here is we're going to replace all of this stuff here with something better.
I'm going to say if symbol that means it's not empty and we're going to do one other test.
There's a really cool way that we can write it we haven't talked a lot about it but I think you'll dig it.
So what we can do is we can use this all function and we can call all and what it's going to do is it's going to check that something is True for every item in a collection.
And then see where it says arable here?
And by them we can write little tiny expressions.
This one will be called a generator expression and what we can do is we can just say something like the value for some collection.
So what we want to do is we want to say symbol is equal to cell for symbol I guess it's cell in row, like that.
Let's go over symbol one.
There we go.
So here what we can say is if this is not nothing and for every one in the row every cell in the row it's equal to the first one and we're going to return true.
Otherwise we're going to return, you know we're never going to hit this it's going to go down and check the others and then check the others and then eventually return False.
So if I've got everything right this time I should have this working.
Alright, 1, 1, that didn't work let's put 1, 2 for the computer and I'll put 1, 3 for me.
Let's have the computer take the second row so 2, 1, I'll do 3, 1 2, 2, we're getting close I'm going to play 3, 2.
Now, the computer is going to play second row, third column it should win right here.
Boom, process is finished the game over, computer has won with this board right there.
Perfect, so now we got this check working.
But I hope, hopefully you can tell this is starting to get kind of gross over here.
So we did this for the rows I haven't checked the columns yet, have we?
Oh yeah, we haven't checked the diagonals yet, either.
So while this works I'm going to just sort of pause this for a minute and we're going to come back and say, well, I guess I could put this down here for you, couldn't I?
So let's just come down here and say columns.append and I'm going to pass in a column so this is going to be a list that has all the columns and then, again, I guess the diagonals they already got that.
So let's go down here and we're going to do this check again but it's going to be col in columns and start to feel this is not great.
Col zero, column, and guess what?
I'm going to do the same for the diagonal.
Call it diag, I don't know what you want to call it.
Now, whenever you have code that looks like this there's this bit, and then there's this bit and there's bit, and it's the same, right it's exactly the same it's just a matter of what goes in here what goes in here the variable doesn't really matter.
It's clear that we should be doing something different.
But let's just show that this is going to work.
Oh, we didn't quite build our diagonals right.
This has to be that list and this has to be that list, okay.
Alright, so now we should be able to win diagonal.
I guess I'll win diagonal this time.
Oops, that's not going to work, is it?
And play two-two, computer can play 1, 3 alright, I'll play 3, 3 this should win the game.
Boom, game over, make that a little more obvious.
But that's good, and then let's have the computer win by column.
What am I going to play play that one, the computer can play 2, 2 and then, let's see one-three, the computer will play 3, 2 and it should win.
It does, allright so we've got winning the game working but here, this is a lot of a mess and this duplication, and not a little bit this is complicated duplication this is not good so we're going to come back and fix this.
But here's our naive version of winning the game.
Technically, tic-tac-toe is over but we can do better.
|
|
show
|
6:09 |
Well we had our find winner done.
I mean it's technically working but remember, this loop is the same as this loop is the same as this loop so let's think about this for a second.
What we want to do is we want to come up with some lists that are just a bunch of cells and check them.
So here we're saying, the lists of cells we want to check and are the rows.
And we want to go through each row and check it.
Here we say the list of cells that we want to check are the columns and then we want to go through each one of those, here and we want to go through each one of those and check it.
Here are the list of cells we want, are the diagonals.
We want to go through and check it.
What we can do that's better is we can say come up with a function that says, give me all the lists of cells you need to check.
Give me the rows, give me the columns, give me the diagonals because once you have those, it's just three symbols in a row, and it doesn't matter if they originated from thinking about a diagonal or thinking about a row or thinking about a column.
The test that you're going to do is just these three lines so let's make this a lot better.
Let's say, def get winning, winnable, winning, sequences from the board.
So what we're going to do is we're going to come up with a list that isn't just the list the rows or just the list of diagonals, but it's the rows the columns, and the diagonals so let's come over here again.
I want to go get the rows, take that away.
I'll even take the little comment bit here 'cause that's still relevant.
We want to have the columns.
And we want to have the diagonals.
Go back over, okay.
I'll say sequences is empty and then instead of just saying create separate columns we're just going to say when we find a column put it into the sequences you care about.
When we get the diagonals, put them in there and now if you have a list and you want to put all the items in there, you can say this and say instead of append which is put one item, say extend which means take all the items in the other sequence and put 'em one at a time in here.
So we want that there and we also want that here like this.
Extend rows.
Alright, we could just in line this but I think it makes a little more obvious what's happening.
So the sequence gets all the rows, all the columns and all the diagonals and we just return the sequence.
Now we don't need to have three loops over here.
And we just say, sequence is equals find what'd we call it?
Get winning sequences for the board put those there call this cells, cells, cells.
And tighten that up a little bit.
Look how much nicer this is.
That was yucky.
And thinking about this, this makes it really easy to understand when we're over here, what are we doing?
We're saying, there's different ways you can win.
You can win by filling up a row.
You can win by filling up a column and you can win by filling up a diagonal.
But as far as checking those, it doesn't matter.
Just if any of those are filled up, we're good.
So we can break that into two parts and make it much easier to reason and maintain both of them.
See, this isn't too bad anymore.
I guess we should check.
Play a few games to make sure this works.
I'm going to try to win by the diagonal.
And it's easy 'cause I get the first pick.
Alright, so 3, 3 this should be the end of the game.
Boom, Michael wins, game over.
Let's try another where the computer wins in a column and we'll call it good if that works.
Alright, getting close.
Every one.
All right, I know if I fill up that two, two one I'm going to be good but the computer's going to beat me with a 3, 2.
Boom, game over.
Isn't that cool?
Isn't that a super slick way that this comes out?
The realization that all we have to do is verify a bunch of different sequences of cells or of symbols, makes this so nice.
So, here's three, so we add three rows and those are just three lists each of which has the cells to verify.
Here we have to come up with the columns.
Kind of going against the grain of our data structure but not badly.
And we put the three in there, and we put the two diagonals.
Then we just go to this and say, you know here's a bunch of different potential ways somebody could of won, check them all using this common algorithm.
Are they all the same symbol?
Done.
So this, I think, is really nice way to cap off this project.
We thought about the most simple thing we could do we broke it up using divide and conquer we started working on them.
The data structure was important.
A lot of the stuff was pretty straightforward.
This one though, maybe we didn't have a great way on the find the winner.
We just said, well we're going to do something gross and just replicate, duplicate a bunch of code make it really just hard to read.
But let's get it working.
And then we came to this realization like actually, this is a lot better and this is what I was getting at with the get started.
I didn't have this idea when I first created this thing.
You know, I haven't technically gone through it before I hit record, but the first time I did go through it I didn't have the idea that it's just it doesn't matter when you're verifying it if it came from a row, column, or a diagonal.
I just said, well there's these cases I got to check and then I realize, this could be put together much, much, nicer.
So you don't have to have all the answers or the slickest way to do something to get started.
You build it out and as you build it you get better visibility into it, more insight and it comes up with what I think is a really nice version of the game here.
Let me do two super quick things.
At the beginning let's just say print out something.
Welcome to Tic-Tac-Toe from Talk Python.
There we go, and then down here I'm not a huge fan of this.
Let's do a little print and let's just do game over or something like that.
'Cause I want to make sure that this is a little more obvious.
Right now, it's not entirely clear that the game is over.
I'll do one more print at the end.
There we go.
I think our game is done.
|
|
show
|
0:42 |
Now that we're at the end and I've given you all these problem solving techniques and ideas I want to remind you to not forget your debugger.
If you're using something like PyCharm or Visual Studio Code you can go through and see exactly what is happening as you're going through your code.
Though if you get stuck if you're trying to understand what the data that's coming from some servicer or from a file or something looks like one of the options is to just put a break point in here and you can explore this data extensively.
Other things you can just put a print statement and pass the variables.
Sometimes that will show what the data looks like.
Not always, but sometimes and that's nice.
But the debugger is definitely your friend if you get stuck and you have a hard time visualizing and understanding what's happening.
|
|
show
|
1:30 |
Remember in the beginning I spoke about analysis paralysis.
This is the symptom or behavior where you have to have everything planned out exactly right before you get started.
For some people this is no problem planning is not their thing Others it's a really big problem and one of the takeaways I want you to get from going through this whole exercise is realizing that I didn't build it right the first time but we still ended up with some really nice looking code.
So we can refactor as we learn.
If you're unfamiliar with this term it just means changing the structure of your code how it works, maybe the data structures you're using but from the outside it should look like it's doing the exact same thing and that's what we did in this check for winner part here.
The first thing that we're doing is we're constructing all the sequences that we have to check and then we're checking them.
We did it in actually, in even worse and more egregious way before but here we're doing two things we're constructing the winning sequences and then we're going through them.
In that part above, it's not entirely clear what's happening so we move that into its own function and if you're using PyCharm you can highlight it, right click and say refactor and you can choose extract method and it'll just go in automatically bring up the style log and write another function for you.
So the new version looks like this and here this is PyCharm calling the function that it wrote down below.
So this is really, really cool and a very nice way to just get started, get more familiar with the problem and then apply the tools to automatically make it better as you see those opportunities.
|
|
show
|
4:04 |
Now it's time for you to get some practice.
Remember, without practice you do learn some stuff but not as much of course.
And boy do we have a cool example that you can start from scratch and really build out in this chapter.
We're going to go and do basically what I described.
I'm going to give you a problem.
Maybe somewhat like something you've seen, but not the same and you'll be able to apply things like divide and conquer and go through it and build it out.
I think you're going to have a lot of fun.
Here we are in the GitHub repository and let's go down its got the standard overview.
The core concepts are me laying out my problem solving techniques.
Here they are.
Divide and conquer.
Have you seen a similar problem before?
Visualize the data.
That could be at Pythontutor.com it could be in the debugger as we just discussed.
It could be just calling print and passing the data, whatever works.
Visualize the data.
Think through the data structures that might apply here.
Is there a PyPI package?
This is an external package that solves this problem.
And you might also check Awesome Python.
More on that in a moment.
And remember, if you feel stuck working through this that's part of the journey and it's also the reason it's so cool to have something nice working at the end because you had to slog through a little bit of it, right?
So it's the payoff there as well.
And finally, just start.
Get going.
You can use your refactoring tools and refactoring and rewriting ideas to make it better once you learn more.
Now, what are you going to build?
Well, there is a game called Connect Four.
This is a game by Hasbro and it looks like this.
The idea is you basically drop items different colored chips into the top.
And whoever gets four as they pile up here either diagonally, horizontally, or vertically wins the game.
Kind of like tic-tac-toe a little more complicated but in terms of the way the code works, not very much.
Here's some info on wikipedia and over here you can actually play it online.
So your goal is to start from scratch and build this, right?
So think about what you saw in the videos.
Have I seen a similar solution?
Choose the right data structure run through your choices there and break the problem into smaller parts.
Divide and conquer, just like we did in tic-tac-toe.
This one will probably take you awhile.
If you get it done in less than an hour and you're new to programming, I'll be impressed.
So be prepared to put a little effort into it but I think it's going to be a lot of fun to have when you're done.
So it's probably not going to be super fast to solve and you know, that's part of the journey.
So now, create a new project and just start.
That's the recommendation.
Alright, before you actually start, one more thing.
I told you one of the techniques it doesn't apply in this problem but in general, if you're trying to accomplish something and you've used your divide and conquer bits to break it down and then you realize there are some steps that are like Download this webpage.
Understand all of the content, and find this thing.
You could do a really lot of hard work there or you could check PyPI over here.
This is where all of the Python libraries are and you can see there's 215,000 different libraries.
There might be one that solves that problem.
So we could actually check.
Let's suppose we want to go to a website download it, and understand it and ask questions about the data that's on the page.
We could look for web crawling and that's one of the terms or web scraping is another.
Awesome, there's a bunch of stuff here.
However, there are 10,000 plus different libraries.
Whoa!
Which one's good?
You want to try 'em all out?
I don't know.
You can also drop in over here and sometimes they'll have a category for what you're looking for.
For example, web crawling.
And down here they list many once you finally get there many of the popular ones.
They have MechanicalSoup.
They have Scrapey some various other ones.
Visual scraping with Scrapy and whatnot.
Beautiful Soup is also another option which kind of a derivative of this.
I'm not sure why that's not listed there.
Probably should be.
But these are some of the more popular ones in that category.
So when it comes down to step five is there a PyPI package?
Maybe use things like Awesome Python to help narrow down the search if you don't know where to go.
Alright, get to it.
Go build a Connect Four clone and have a lot of fun.
|
|
|
58:16 |
|
show
|
3:19 |
It's time to add some permanence to our program, so far what we've done is we've created a couple cool games and some challenges like that guess the M&M count but there was no memory, there was no history there was nothing permanent about what happened in the game.
You played it and then it vanished, it was over.
So what we're going to do in this chapter is we're going to work with File IO and different file formats so that we can save a history of what's happened in our game.
We're going to create a leaderboard for our Rock, Paper, Scissors game but that's just interesting, that's kind of fun it'd be cool if you're in the lead and whatnot but what's really going to be powerful is we're going to allow people to extend and modify the overall gameplay of Rock, Paper, Scissors entirely just by creating a file and using it instead of typing stuff into our source file.
It's going to be both easy and amazing.
So, I think you're going to have a lot of fun in this chapter and it's going to really be a big bang for the buck for what you get.
Now let's just talk about File IO in general, real quick.
There's all different kinds of files that we might want to work with, a very common one is some form of text file, this might have some kind of entries in it you can pull it apart and work with it that way so you're reading basically lines of strings in these text files or you're writing them for other people.
One special version of this might be a log file this is like a history of what's happened in your program.
Today the game was started and then player so and so decided to play a game and then they played rock and they lost and they played scissors and they won and now such and such, right?
It's just a kind of a history of what's happened.
This is really important in websites and database systems and API and things like that because you want to know what's happening in your program, you're not the only one using it, all the people on the internet are doing things usually good things, sometimes they're trying to abuse it and sometimes they're just problems and things don't work right and you want to go back to these log files.
So, we're going to see about creating those.
Now, those are just sort of free form things you put in as text and you can edit them with some kind of text editor.
We're also going to work with dedicated structured file formats, something called JSON these are very, very similar to Python Dictionaries but they get saved and loaded into files.
This is traditionally used for exchanging data with some form of web service, they expect this structure data and they can pull it apart, but you'll see it's also going to be really useful just for working with files for us.
Another very common format is, I've got some kind of table of data, so you can create a comma separated value file this is a special version of a text file as well but it lets things like Excel and Google Sheets and other spreadsheet like software work with this.
And these are extremely easy to create in Python as well.
And finally, we might come across some form of binary data which you have to create slightly differently like maybe we want to create an image or a media file or something like that.
So there's a wide range of formats in Python.
What we do to work with them, there's some commonality across all of these, but there's also some uniqueness.
The way that we work with text files, for example is different than with binary files like a JPEG.
Also, the way we work with JSON data might be different than the way that we work with a log file but you're going to learn about the general principle behind all of these, and we're definitely going to work at least with JSON and maybe TXT as well.
|
|
show
|
1:46 |
Before we dive into this chapter I want to just say a few words about your progress in this course.
If you've made it this far you've been doing really well.
That last chapter is suspect for many of you was pretty challenging, we used a lot of complex programming ideas some interesting data structures, we saw some challenging problems in non-obvious ways.
Then you get to the practice exercise and you're building Connect 4 from scratch.
So that was probably a lot of work if you're new to programming.
And if you're feeling like this course is getting harder and harder, you're in luck because you just passed Max Q.
What the heck is Max Q?
In spaceflight and all sorts of flying things actually it's the point of maximum dynamic pressure on a spaceship or airplane or whatever it is you're talking about.
What does this have to do with you?
Well for spaceships they have to push super hard to get going and they go harder and harder and the faster they go the harder it gets for them to go faster and actually there's this point where they have to turn down the engine or it could damage the spaceship.
But once you get through this point, this may be like 1000 kilometers an hour, then the spaceship goes faster and faster and faster like 20 times faster up to tens of thousands of kilometers per hour and yet all those steps are easier and easier because the pressure higher in the atmosphere, speed, et cetera put together is actually less so I feel like that last chapter that was Max Q that was one of the hardest thing, all of the things coming together and now we're going to have a lot of fun putting some file IO and cool features into our game and working with some external libraries and what not so hopefully you can feel as we go through this chapter and the next that this is getting more easy and things are just starting to flow better for you.
I hope that's the case and yeah this is one of my ways of viewing the world this Max Q theory of working through whatever it is, not just spaceflight but even studying new topics like Python and programming.
|
|
show
|
3:00 |
Remember how we had this dictionary that we were creating for choosing which roll was played and then what beats it and what is beaten by it, and so on?
Like here if we play rock we know that rock defeats scissors but is defeated by or loses to paper?
Well, look at the top here.
If we change this where we store this from a source file into a regular file, just a data file like here we called it rules.json we can load this at startup and it's super easy for Python to understand this JSON format.
The first thing that we're going to do is we're going to use a JSON file that looks very much like the stuff that we actually had built into Python.
We're going to use this to allow the rules of our game to be extended or controlled from the outside without even touching the program or the source code or anything like that.
Now, that might seem like overkill like, Well we already have it in the game file.
Why not just leave it there?
because, there's more variations to Rock, Paper, Scissors and some of them are totally awesome.
This place at umop.com they've got a couple variations that I think are really fun.
So here you can see at the top we have rock at the bottom we have paper and on the left we have scissors but now we're adding three no four more things.
Fire, water, air, and sponge!
And you can click that link in the bottom to learn more about it.
So what you're going to see is that we could actually create this version of Rock, Paper, Scissors without touching our software by just changing that rules file.
And that's going to be really cool because that means that people that get our game they could actually change the rules just by editing a simple text file and not even knowing programming.
Sure, we could code this into there, right?
We could actually put this one and make it a choice but you know what?
There's also 25 way Rock, Paper, Scissors and I think there's even like 100 way Rock, Paper, Scissors.
There's some really, really insane stuff so this one is really fun.
You've got the snake, you've got the ax you've got the devil, you've got the wolf the cockroach, the alien, so.
This one's really, really fun.
And you can check it out at this URL here as well.
We're not going to do this because it would be a lot of work but I do want to make a quick comment about the data structure stuff that we did.
Remember our if statements we had three if statements.
If it's rock, then if the other player played rock do something if they played paper, do something and so on.
So we had nine nested if statements.
Because there were three times three things and ways to play the game so that it ended up with nine but it seemed kind of bad but not terribly bad.
If we do that with Rock, Paper, Scissors for 25 way.
RPS-25 we're going to end up with 625 if statements in a entirely non-maintainable way.
I just want to point that out because this thing here would not be very hard to create an add to our system that we're going to create here either by putting it in a source code or this better version with a file we're going to use.
So I think that really drives home the power of those data structures to do a much more general solution than to just hard coat it.
Okay, so our first challenge is to move that data structure out of our program and into a file so that we can then extend it and add some of these game features to it.
|
|
show
|
5:51 |
Let's jump over to our rock, paper, scissors game.
Now I have a new project here.
I've made a copy.
You can see over into chapter nine.
Working with files in the GitHub repository.
This is just a copy from CH08 or CH07, whenever we worked on it last.
Now here we are.
It opens up actually right to the subject of this whole demo here.
We want to take this code which right now is an RPS game.
And it works fine, this is a Python dictionary right here.
And what we're going to see is that it's fine here but if you want to extend it you know you got to change the source code and that's not really what we want.
We want a separate file that anybody who's even not a programmer can mess with and then we can try to load that up.
So what we're going to do is we're going to go over here and we're going to create another file.
We're just going to write this by hand and then we're going to load it.
Later we're going to create a file with Python but right now we're just going to read a file.
So I'm going to create a file called rolls.json.
We get to pick the name.
Call it whatever you want.
I'm going to call this one rolls.
Now it's unhappy 'cause it's not structured JSON.
JSON basically follows the same rules as Python dictionaries for the most part so what it wants is something like this and that'll make it happy.
So let's just go over here and copy this bit.
We don't give it the name we just take the value or whatever and put it over here.
Now all of a sudden it's freaked out.
It looks really broken.
Like everything is broken.
Well JSON is more picky than Python.
Remember in Python, we can have single quotes or double quotes.
JSON, it only likes the single quotes.
So let's just replace all those.
And ta-da, it's magic.
The other thing is that Python allows you to put the comma on the last item.
This is nice so that as you add new items it doesn't, you don't have to worry about this but JSON also doesn't dig that.
Other than that, here we are.
We have this working.
So let's go and delete that.
We can maybe set it as empty just for starters.
But let's go over here and we can do something like write a function or express there's going to be a function called load rolls.
And we're going to go put that down on the bottom.
Now one of the things we got to deal with that's new for us is you see this rolls is outside of function?
In order to work with it specifically in order to write to it 'cause we did work with it in other places but to write to it we have to say first global rolls.
And now once we've done that we can say rolls equals whatever.
If we didn't have that then you get a warning that this one here is shadowing, hiding the outside one.
You're not actually working with that.
Okay so what's going to be the file name?
It's going to be what we typed.
Check that out, how sweet is that?
PyCharm finds it for us.
Thank you PyCharm.
The file is this.
Now we're going to start with just assuming that everything is kind of lined up next to each other and then we're going to improve upon this.
So what we need to do is we need to go and use a library called json.
So import json.
And JSON knows how to take this file format and turn it into a Python dictionary exactly like what we had before.
But what we have to do to make that happen is either give it text which we no longer have or give it a file stream.
So first thing we got to get is a file steam.
We'll say file input.
Going to be like that, so you just have this built-in function called open.
See it takes a file name a mode, this says is it read, write is it text, is it binary are you appending to it and so on.
And then encoding.
We want to go over here and we're going to say filename.
The mode is r for read.
And defaults to text.
If we wanted binary it would say rb.
We're going to set the encoding to utf-8.
That's a pretty safe bet.
And then we're going to say rolls = json.load.
Now these names are not super great but load means load from a file.
See that fp, the file pointer.
Why couldn't they say file pointer?
I don't know, they don't need to save that much space, so.
That's what we're going to do.
If you had a string you would pass the string to loads.
Now that wasn't too hard was it?
We're going to open this file.
And we're going to work with it.
Now the next thing we need to do is make sure we close it here.
Otherwise that file might get locked something else tries to open it it can't because this file pointer has it open and so on.
There's going to be some improvements around that but let's see if it's working.
Remember up here we have nothing here right now.
Right we're going to wipe this away.
So what we're going to do let me just make a super minor change.
So over here.
Nah, nah I'm not going to change it.
But notice we're just going to load this up and it should work the same.
If everything works let's just say do a quick printout here.
Let's do print.
load_rolls.
We want to put basically the rolls.
Not keys.
It'll show us that but I don't know that it's going to come up right so we can say let's try this.
Let's try it and see what we get.
Dict keys.
I'd rather have it just be a let's just do a list.
That'll make it look nicer.
Check that out.
We loaded those rolls from the file.
Remember that's not what's up at the top.
There's nothing here.
Super cool.
So now let's just make sure that we can still play it.
I'm going to play a rock.
Okay I played rock.
Computer played scissors.
I took the round, awesome.
Going to play rock again.
Going to go straight rock on this one.
They played rock.
Ooh they beat me with some paper.
They beat me with paper.
They beat me with paper, wow.
My decision to go straight rock was bad.
Nonetheless though the game it's unchanged right?
It doesn't seem like anything has changed because we were able to load the same information up here.
Yeah, very, very cool.
But now the difference is whoever wants can just go edit this file and that's going to define how the game works.
Specifically they can add things they can take away things change what beats what.
Mix it up, get crazy.
So it's a really cool way to do that.
And look how simple it is.
|
|
show
|
2:37 |
Loadings the rolls worked great but there's a few things that we need to work on.
First of all, notice this.
Now this is a topic we've not covered at all we've experienced it, but we haven't covered it.
If there's a problem with some code in Python what happens is Python throws what's called an Exception and that means if you're coming down here, and here and like right on this line there's an Exception it's not like this comes back as nothing.
It's going to stop what it's doing figure out if there's some kind of error handling block it's not here, so it's going to go see who called this and it's just going to leave it's just going to stop on line 95 and carry on.
You know, maybe worse if so the error happened on 36, or 96 the file's going to be open, and we're going to leave and that could be a big problem.
So we want to be safer about that.
We want to make sure that no matter what even if there's an error we call this close function.
So we can, there's a different way to write this these three lines of code here.
Check this out.
This is a new construct, it's called a Context Manager.
It uses the 'with' keyword so you say 'with' whatever we had here as whatever the variable name is, so fin all right take that, put it there and then we indent into this block here.
Whatever happens in this block is going to be when the file is open and then when we leave you can't really see it here, let me put some more you look really carefully see there's a vertical line right there?
This is PyCharm hinting oh all this stuff is inside the block.
Whenever in the with block whenever we leave this and we go back to, like the next thing is print it's going to automatically call close.
And importantly, it's going to that even if there is an error.
So that, that bit right there is a safer version of this cause this doesn't check if there is an error and also call close.
That would take like three or four more lines of code.
So we're not going to do that.
We're just going to do this.
Whenever your working on files always use a with block there.
I'll leave this in as a comment for you but we're not going to run with that.
Just one more time, make sure it works.
Yes, it loaded it up all fine.
Perfect!
So, everything is looking great this with block, this context manager is recommended any time you have something that you must must must close, clean up blush, shut down whatever as part of you've opened it do some stuff, and now close it even if there is an error.
This is common in databases if you're writing to a database you need to have a transaction you want to either commit or roll it back if there's an error.
So it appears in many many places also networks and socket connections but files is one of the places you'll definitely run into these context managers so don't forgot to use them.
|
|
show
|
3:29 |
The next thing we need to talk about with our files is locating the file itself.
It seems easy, here's our game, here's our file that's the name of the file, we try to load it it works.
However, the reason this works is because the working directory as far as the program is concerned is this folder, so we can find this file in that folder.
There are many reasons that might not be the case.
We can force this to happen if we go over there to the working directory and we just take away rocks game like this, and we run it.
Yikes, that's not loading up the rules like we were hoping, was it?
And we got a file not found error one of these exceptions and the details is no such file or directory rolls.json.
So we want to be able to load this file no matter what and the way we're going to do it is we're going to say go to whatever this file is get the directory of that and then put it together with this file.
Now, we can get the directory well, we can get the name of this file using this little trick here.
Say local file, is going to be this.
It's just going to be dunder file.
We can print out local file real quick.
So let's run and see what we get.
We get the error.
Here you can see this is the actual file.
So what are we going to do?
What we want to do, well, we want to get rid of this part and we want to get the rest of this here this whole ginormous name and then we want to append to the end this and make sure there is a separator.
This is tricky in a couple of ways.
First of all on Windows this would be \ separating the directories in the file on macOS and Linux is /.
There is other issues around this as well that get really, really challenging.
If I'm going to combine the directory and the file I got to make sure that there's a separator either those two that I need it has to be there or it's going to be like the directory rows.json, which isn't great.
So there's a bunch of little juggling that gets tricky here and luckily we don't have to juggle it.
There is a library for this, it's called os.
We import os at the top and we come down here we can say the directory is going to be os.path.dirname from the file.
I'll just use the file directly like this.
And that's going to give us the directory.
Let's go and print out directory.
We get the error.
We start to fix it but notice now we've got just the directory.
That's a good start.
So the next thing we want to do is we want to get a file it's going to be the directory with this on the end of it but with a separator.
So we can easily go os.path.join and give it the directory and that, and then let's print out filename.
And now it's going to be the right place no matter where the working directory is.
Let's run it, it should work now.
Look at that, it's back.
It loaded it, and if we go and look at the file here it is, look.
Even though we didn't have this one with the separator or this one with the separator, oops this one with the separator, it added that back.
On Windows that would be a \ on the other systems a /, on the POSIX systems.
Really, really cool that we can do this little trick.
And let's go like that.
There we go.
We don't need to print that stuff out.
That was just for us to see what was going on.
So we're going to go to a file though we know about this one and we're going to say get the directory, just here and we know that right next to it in the same directory is this, so we just use this name.
You can also use like dot dot to say go up for directory and things like that.
So it looks like our file loading is much safer and it's always going to work regardless of what the working directory is.
Tada.
|
|
show
|
5:00 |
Remember I told you it would be a good idea to move the rules into its own data structure and because it was a dictionary it's almost identical to JSON so why not that?
The motivation was well then we could change it or extend it or work with it from the outside so let's go ahead and just do that huh that'll be fun.
So over here we have the seven way rock paper scissors with rock water air paper sponge scissors and fire.
Though if we go down here you can actually find an easier way the way to interpret this diagram is air beats rock because air is pointing at rock, but rock beats fire 'cause fire being pointed at by rock.
Now I find that a little bit hard to follow, so let's go down here and you can here even a like more colorful version rock pounds out fire and crushes scissors and sponge, so we can use this actually this little bit here to help us figure out what we got to do for our file.
So let's go over here to this one.
And first of all let's go and duplicate this real quick.
And make that empty that empty that empty that empty.
We're going to have fire, we're going to need we have three we're going to have three more, four more.
Sponge, air, and water.
Okay now let's see one two three four five six seven.
So that's all of them and let's just do a couple real quick together and then I'll just pause the video and I'll just do the rest myself.
Okay so for rock, rock pounds out fire so that means it defeats fire.
Now be super careful here look what I typed how many things is in that list on line three?
Looks like two but in fact it's one 'cause there's a single string that just happens to have a comma in it so be real careful that you put quotes there you go now there's two things so rock pounds out fires, crushes scissors and it beats sponge.
And it is defeated by something that beats let's go look through this let's see paper covers rock so yeah it's defeated by paper what else?
Air erodes rock so air is going to beat it.
And water also erodes rock okay let's see that will have rock and let's have the sponge.
So sponge soaks paper, it uses air pockets apparently and it absorbs water of course it's going to be water but what defeats sponge we have rock, fire burns it and scissors cut through it.
Okay so let's just kind of run the game with this.
Now to verify that I'm only changing this file and nothing else is happening let's go and run this in a different way.
Let's run it over here separately so I'm going to say Python 3 and then just the file and look at that we loaded up all those and now what are we going to play, we know that rock and air are pretty capable so let's try some air this might not work because not really sure what's going to happen, they rolled scissors got to wait til the computer throws something that we know about.
Alright I guess to get anything meaningful to come out I'm going to have to finish out this thing 'cause there's just too many that don't work with air.
But nonetheless, we're off to a good start you can see that it loaded those up.
I'll go finish mapping this out and then we'll come back to the video.
Well here we have it the seven way rock paper scissor rules and going back it turns out it's easier to use this diagram here actually to figure out what to type here just look okay this one points to those three, so put them in defeat.
But here they are we have it all written out and I think it's good I've checked it it seems okay but I haven't exhaustively tested every case, we could do that.
But let's just play around and see what happens here.
If you want to play it you can see it's delivered all the roles and let's put it over like this so you can see what's happening.
I'm going to play some sponge, they played scissors, scissors cuts sponge see what are we scissors they're defeating sponge then the computer takes the round.
As per usual on play six, the computer played I rolled air the computer rolled paper and let's see somehow air eats paper, air is defeated by paper yeah so they beat me with paper I'm going to play some fire.
The computer also played fire.
Do it again, they played paper I'm burnt up that paper I just keep going, I played fire they did scissors I melted the scissors all right here we go I'm going to try to take it down with some sponge.
I did sponge they did fire ah man they burned it up.
As per usual I lost rock paper scissors, even the seven way one look how incredibly cool this is.
All we did was take this same basic idea and extend the rules over here we literally didn't touch the source code to make it understand that there are now more things to throw or that there are these rules between them.
So hopefully this tells you or shows you how powerful these data structures are and this general way of programming once you get the right model in place.
If you want to go and add 25 way rock paper scissors honestly it wouldn't be that hard.
|
|
show
|
1:04 |
Lets quickly review loading data from a text file as JSON.
So there's actually a couple of steps involved.
We wanted to manage a global variable so we had to say global rolls we're going to write to that ultimately.
We need the JSON libraries so we imported that at the top.
We also saw that the working directory affects where Python looks for non-fully specified paths.
Right, it's just rolls out JSON as well.
It's wherever you are and if that's not where yo expect things don't work.
So we use the os.path module to do all sorts of cool stuff.
Get the directory from a file and then take a directory plus a file name and join it together in a operating system independent way.
That was cool, we came up with files.
And then we wanted to use the open function pass it the file, r to read set the encoding, store it in a variable fin.
But we wanted to make sure we did that safely and closed it up no matter what so we put it in this with block into a context manager.
Whew!
Now we're finally ready to load our JSON and that's just one simple line.
So we just say json.load, give it the file stream and boom, out comes the Python dictionary that was stored in that file.
|
|
show
|
0:44 |
Now we're going to do something really fun.
We're going to have a leaderboard.
I mean that'll bring you back to any arcade game, right?
Here we are in some arcade, who knows where.
And you can see all the players who have played and got high scores and whatnot.
So we're going to add that to our game.
And we're going to reuse a lot of the same ideas but instead of reading files, which we'll also do, but in addition to that I guess we're going to be writing files.
We're going to have to be figuring out who the players are what their scores are, save that back to some file and so then when we play the game again load the program again, we're going to be able to read that and then carry on from there.
We'll actually see like computers won seven rounds ever, and Michael's one who knows one or zero, that's going to be how it goes for me.
But something like that.
We're going to build a leaderboard like this and it's going to be a lot of fun.
|
|
show
|
6:14 |
Well, the first thing that we need to do if we're going to have a leaderboard is figure out who is playing right?
We can't just have you all the time and computer the other time.
So let's do a cool little trick here.
Let's say, I'm going to write a function and it's going to be get_players.
And what we going to do is we're going to use this cool little trick where we can return more than one variable or value from this function.
Technically, it's still returning one thing but it will look as if we're doing more.
So we'll say what is player_1 P1 just to show you these can be distinct well if they input player_1, what is your name?
And then down here we'll say P2.
For now its just going to be computer I guess we could capitalize their name.
And up here we'll say player_1, player_2 is equal to get players like this.
And then as is in like so.
And now we just need to return these values you don't need that anymore.
We can just say return, p1, p2.
So we return this as what's called a tuple goes back as a pair and then it gets set back into those two variables.
Pretty cool little feature of Python.
So let's just see that this works here.
What is your name, player_1?
My name is Michael.
Great.
I'm going to play rock.
Michael plays rock, computer rolls paper.
Again, computer takes a round.
That's good, and that's important because we needed to actually have different names so it would put them into the leaderboard.
We can do that.
So let's go down here to the play game part.
And then we go down or we have a winner.
This right here is great to have the wins for the round but actually what we want to know is we want to record the winner here.
Ah, sorry, here, for the overall winner.
So after this is over let's do something like this we'll call it record win.
And we'll pass the overall winner.
Now, what is this overall winner?
This is going to be the name like Michael or computer or something like that.
So let's go down to the bottom and we're going to define a function, call that and we'll change this to winner name.
Alright, well what we did before I'm going to delete this now.
We got it saved in source control in the history there.
What we're going to do now is something very similar to what we did here.
So we're going to come up with a directory and a file and we're going to kind of do the same thing.
Change the name of course we better not put it in the same file.
We'll call this leaderboard.json and we're going to use JSON here as well.
We're going to, this is the last thing we're doing a JSON we're going to move on to another format momentarily.
But let's just use JSON.
You'll see that works pretty well.
Now we want to write to this file.
And reading it is not what we want.
And I'd like the file output stream name so I'm going to change that technically the variable name doesn't matter.
And we're not doing it this way we're not getting data back we're putting data into it.
So we're saying save, save, let's try save, no.
Right, nope.
Dump.
Whatever.
That's a bad name I think, but that's what it is and what we want to save here is some kind of leaders or something like that.
So, where does this leaders come from?
Well, we're going to need to have another function that loads this.
So I'm going to say, come over here and say load_leaders.
And this one is going to be really really similar to this one.
So you'll see.
So let's go over here and call it load_leaders.
This one's going to try to read this file.
Now this is going to be interesting as well.
Return json.load.
Is that going to work?
Mm, probably not.
Let's go find out.
So UI.
My name's Michael.
I'm just going to play one a lot.
Oh ho!
Error crash, no file, such and such.
And you can bet that that's the leaderboard.
If we click here, we can see where it happened.
It happened right on that line, 116 for trying to load it.
You can't load a file that doesn't exist.
So we got to do a little test here we got to say first if, if the path exists now we want it to be not the case.
Then, what are we going to do?
We're going to turn an empty dictionary so that we'll get started with no data just an empty dictionary but if the path does exist that means we must have saved a dictionary there we're going to load it up.
Alright.
So that should work.
And then, we're going to do this.
We're going to say if when a name in leaders leaders of winner name plus equals one.
So we're going to store the name and then one, two, three, four, five, six, seven.
And we say else.
This is just going to be equal to one.
Why do we got to do it that way?
Well, it's a little bit weird.
The problem is if you try to say += and it's not there, this is going to crash.
If you did it again it would return something funky as well.
There's other ways to do it but I'm going to do this.
Think it's good enough.
Now, let's go ahead and play this game.
Going to be Michael.
Alright, the computer has a one, no surprise, right?
But check this out.
We've got some externally added files.
I'm going to ignore those for a minute but here we have leaderboard.
With that, the computer won.
The computer has one, so the computer has won.
Let's go and play it one more time and see what's happened.
I'll just leave it here.
I'm Michael.
Ugh, the computer won again.
Notice how it changed to two?
Man, I better win one of these.
My name is not going to be two.
Let's try this again, my name is going to be Michael I'm going to play two this time that'll trick the computer.
Ugh, now it changed to three.
Play it a few times 'til I win.
Yes, I won the game!
Now check this out.
Now I'm up here as a one and so on.
Whoops, long as I don't mess it up.
So we're storing this information.
That's pretty cool, right?
So now we're recording who the leaders are.
We're not doing too much interesting with it but we do have a persistence across the plays.
We're trying to load it up.
If there's no data at all we're starting from scratch so we create a empty set of history or empty set of leaders, otherwise we give it back.
And then what we do on this one is we get the leaders as they are and then we update that and we save it back over top the same file.
Looks like it's working great.
|
|
show
|
6:38 |
It's great to have this leaderboard but it's not so much fun if we can't actually see it, right?
So what we're going to do is, we want to come up here to the top and we want to call something up here, after sure headers where we can show the leaderboard.
So let's go over here and say, show_leaderboard.
like this, and when we just maybe put it right down here like this.
Daft show leaders, get everything lined up just right.
Here we go.
Now, what we need to do is load up this file.
We could go write that code again but we actually already have everything working.
We just have this load leaders function already.
We could print out leaders and see what we get.
Let's run that.
There's the leaders, that's not incredible but it is showing it right?
So, let's go ahead and put this out here, different way.
Instead of doing that, let's first of all just try to print out a new line, or print leaders.
Before, somehow I want to get the values in here.
Now, when you have a dictionary, there's some cool ways to print this, not to get to go through them and get information out.
So we could say: name, wins in leaders.items.
If you ask for items, you get both the key and the value back.
So, we just print name and wins for a second just to see what comes out.
Look at that, that's pretty cool!
Not quite formatted all the way, but pretty good.
Do a print here, like that.
And one more print.
Okay, so instead of doing this let's put a little f-string in here.
We can put the number of wins, like this.
And if you had high scores, like 14,220 you want to comma-separate those, you can do this little trick and it'll do digit groupings like: 1,000.
And then, well maybe put the name.
That looks good.
Let's put some dashes, like that just to give it a little formatting.
So you can see, we have the leaders three for computer and Michael has well, one, I guess that's better than nothing.
Let's try to play one more time.
I'm going to play scissors, I'ma play some of this play some of that.
Oh, here we go.
Yes, I've won the game.
Let's run it again.
Remember up here, before I run it, had one win.
Run it again.
Look at that.
I'm moving up the ranks.
Wanted to try to play while here, I'll play Hannah.
Do some Hannah here.
Player one.
Four.
Oh, it's not looking good for you, Hannah.
The tie.
Oh, the computers won, got to play another one to get her name to show up in the leaderboard.
No, not again.
Yes, finally!
Hannah has won the game.
So now she should show up here.
Look at that, it goes six, two, one.
Now, this looks great, right?
That's how leaderboards work.
It has the highest one and then the next highest one and then so on.
But it's just a coincidence.
If we go over here and we like change the order with the computer last, now it goes two, two, one, six.
That's not right.
So we got to do a little bit more work to fix this.
Now, dictionaries, they don't have a sort, a sorted order.
So what we need to do, is we need to go and say sorted names or something like that.
What we come up here and we can start out by having this just be the value.
So we could say this is going to be a list of leaders.keys, like this.
Now this is going to give us the keys.
Actually I think we could do this better with items.
Yeah, do with items.
Number of sorted name, not sort.
Now, this is not at all obvious but it is incredibly cool.
See that key thing right there?
I want to say key equals, and in Python you can create these little tiny expressions that are like functions called lambda expressions.
So let's say lambda, and then you say the variable that comes in, I'ma say L for leader right, the leader entry.
And what we're going to be able to do is you just say what value do you want to sort, this went by.
And it's going to go through and get the values for all of them and it'll do a natural sort and out.
Like, for example, we could say here's a date like if it's a user, when were they created.
We want to show all the, sort by the newest to the oldest or oldest to the newest and so on.
So here we can get the things that come back.
The name is the key, it's the first item zero.
The second thing that comes back in items is the wins, it's going to say that.
Now if we runt his, I'ma go through here.
So this where the leader this here, like so.
Let's rename this to sorted leaders or something.
Let's go and run this again.
Now it's sorted.
Awesome.
But it's sorted in the wrong way, not awesome.
So, one more little technique here.
When we go to our sort, we can come down here and say reversed is true.
So instead of sorting it smallest to highest highest to lowest.
Phew, look at that.
There we go.
Now no matter what order they're in it's going to show the leading leader and then the next one and the next one.
Maybe we only want to have five in our leaderboard.
So there's one more cool trick you can do in Python.
You saw that I can get into list elements like two, or five, that would be the sixth element.
You can get ranges of these.
You can say zero to five, like this I mean zero to two, so you just see the top two.
Like Hannah won't show up.
Here you see just computer and Michael.
So if we put just zero to five then our leaderboard won't show everyone who's ever played but just the top five players, because it's sorted.
That's pretty cool, right?
So, here's our leaders, maybe I'll put one more little divider here like this let's run and see how it looks.
I'm not sure I like that divider but there it is, we've got our leaderboard right there.
Let's play one more game, let's see if Hannah can take another round here.
She does.
She's up, now it's tied.
Right now it's tied, just see who's going to go there's no rule for figuring out who goes first when they're tied, so-- Guess we'll just get lucky, whoever is in there first.
All right, well that's it, that our leaderboard.
We did some interesting stuff.
We were able to record down here.
Win by change of this to write and then using JSON dump instead of json.load, there's no problem here Python just thinks it's misspelled.
That's just what I want to call it.
So here we go.
And then we're going to show our leaderboard over here, nice and easy.
Just load it up, use the same function other parts of the program are.
We have to do this cool little sorting trick here.
And then we're going to just print them out.
Pretty standard.
Wow, that leaderboard is awesome, I love it.
|
|
show
|
1:28 |
You already know how to load JSON.
And it turns out it's actually really similar to save it.
So what we have to do is start with some object that we want to save.
And it has to be what's called serializable or convertible in to JSON.
There' weird things that don't work like datetimes for some reason are not supported there.
But if you have simple stuff like lists and numbers and strings and so on then it's all fine.
So what we have here is we have our leaders.
And when we said load leaders we either get an empty dictionary or one filled out with names and then their scores.
Right?
Either way we want to save that when we record a winner.
So we're going to go over here and we're going to find the winner.
Increment their value.
Remember we had that test to see if they were in there or not.
And then we got to do our file trick again to get the full path.
Not the relative path or the short path with no directories.
We use our width statement.
We open up a file just like before.
But the difference this time is that red W.
Instead of giving it an r for read.
We give it a w for write.
Now it's not clear from this here but this means overwrite.
Replace.
It doesn't put it on to the end of a file.
You got to do something else for that.
And I'll talk about that later.
But for now if you want to write completely the contents of this object in to that file as JSON.
You're going to put a w.
And then we just go to our JSON library.
Which we've already used.
But instead of calling load we say dump.
Boy do I wish they called that save.
Anyway, dump.
And we pass the object to be saved.
And then the file stream to save it to.
And that's it.
You've now loaded up this JSON through load_leaders.
And then you've made some changes and saved it back right here.
|
|
show
|
1:59 |
Let me pull back the covers just a little bit and have you have a look inside of how you're watching this course right now.
There's 10, 12 servers throughout the world that deliver video to you and the site uses geolocation to figure out which video server is closest to you and then it will route that over based on your IP address.
So, one thing that's important for us to do is to make sure that our files, the video files, are always consistent.
We edit one, that it's edited in all 10 places, not just one or two or five places, it can get really confusing.
So we have this software that will go around and around and it will check one location where we drop our files and then will automatically verify that every other location in the world, Brazil, Tokyo, Sydney, Frankfurt or wherever has exactly that same file, same size, whatever.
Now, if it's different, it's going to download it from the source place and distribute it around here as you can see in this example here.
How do I know that this is working?
How do I know that this has happened or is happening now?
It's because that application, it logs to a file a text file, and it appends line after line after line as it's doing its work and on Unix, Linux macOS you can run this thing called tail and what it will do is basically just show you the outputs of a file at the end.
They show me here, they say, tail -n 1000 -f and give it the file name, that means show me 1000 historical lines and then anything that's new update the screen with it.
So, we're going to add this type of functionality to our rock, paper, scissors app.
Now, of course it's not as important because you're interacting with it.
This is really important because there's no visual aspect to this at all, the only way without logging I would know what's happening, is to just go to those file locations and verify, yup looks like the files are getting copied here.
That's not good enough, you want to have some kind of output and see it as the time and how important the message is and what the message is associated with that, its source all sorts of cool stuff that we're going to be able to add to our program here in a minute.
|
|
show
|
4:29 |
Next up we want to add basic logging.
In the previous video you saw how we're using logging on the background services that organize and manage the video files at top life and training.
We're going to do something less ambitious.
We're just going to keep a history of what's happened with the game.
So okay if there's an error or something weird happens or we just want to see who's played and done what we can go back and check that out.
Let me go down here to the bottom and write a function like def log and it's going to take a message.
And for now, its just going to print not really and then the message.
Not really going to log it we're going to figure out how to do that in a second but the first thing we want to do is just use this function in various places.
So lets go over here in main and we'll say log, app starting up.
Like that, and over here we printed out those before, remember that?
Let's just log we voted those rolls.
And we can even do it better from, we could do I guess we could get our file, os.path.basename(filename) This will unroll the full directory and just say the short directory.
That's probably good, cause the full path is really long and we don't want to see that.
Okay, so we are logging that.
Let's go over here and we can print out that there's a new game happening.
Let's see, maybe do that at the top.
Right here we could have the player that logged in.
We could log, player one as logged in.
That would be cool.
And then down here it probably makes sense to do it inside this function.
We can do a log here we can say new game starting between player one and player two.
Let's just see that something is happening when we run this.
Okay, not really.
App starting up.
Not really, loaded these from rolls.json My name is Michael, look, not really, Michael is logged in.
We are going to get rid of this not really.
I just want to have some kind of distinguishing thing to remind me, yeah yeah we've still got to go put that in a file.
We shouldn't be seeing it here it should be going to a file.
But let's get the messages together and then we're going to save them to a file.
Alright, starting a new game between Michael and the computer.
I'll just play this out real quick.
Because you know I'm going to lose.
Oh!
Oh!
Oh!
I could win!
Nope, of course I don't win.
Of course I don't win, because the computer always beats me.
Alright, so over here we are going to play around.
Let's do, this stuff, you know where we have the print.
Usually we see the print, maybe we went along.
Maybe we don't.
We could have some interesting things in our log function that say sometimes we want to show that both the screen as well as print it out as well as save it to the file.
Now we will just put a quick message here.
Put this all on one line.
And let's log this out here.
If we have this twice, probably don't want to have it duplicated so we can do a little introduce a variable.
And call this a message, and then print out the message here.
That's a cool trick right?
And then, same thing here.
The noise work.
We can make it.
Alright, that good.
And then, I think we are going to have maybe we want to have this come out as well.
And then finally we will log this.
And again this should really be not duplicated, right?
I'm really starting to come around to the idea of having the log message have the option to send it to multiple places, when you break lines.
Okay, that's not a big deal.
Alright, I think that might be it.
Let's go ahead and run this one more time just to see that we got the messages.
Okay, app starting up.
We know our rolls and the rules.
My name is Michael.
Michael is logged in.
Our role is starting round one.
Okay, so in this round Michael rolled rock.
Computer rolls sponge, I pound out that rock.
I take the round.
Score is 1, 0.
And let's just finish this out, and maybe I can move up in the leaderboard.
Nope, of course I can't.
Though, there we go.
And then we are logging that computer wins the game and then maybe log, game over or app exiting up here at the top.
Alright, so this is what we are going to do with our logging let's do, log game over.
Cool.
Now, this is great we got all this in place but again the not really bit means we're actually not doing anything interesting with it just yet.
It's going to be what we do next.
Let's call this part done, for now.
|
|
show
|
6:07 |
Remember when we run our program our log messages, they come out here but they're not really going to a file that's why it says not really and they shouldn't be going to the screen they should be going to a file.
So let's work on this for a second here.
What we're going to do, is we want to write to a file we'll have a file name, remember this we tend to do that trick about os path lets do it again, coz the same rules apply we want this file written where we would like it to be written.
So we're going to go over here and we'll just call this our rps.log.
Let's call it like this, .log.
Now in a real system you might cycle this by day so you have a file with the date mixed in there but for now we're just going to do this.
Now what we want to do is, we want to open a file and write to it.
So again, we'll do what we've been doing with open file name, now we're going to write to it we had W before but if you have a W here and you open and close it and open again that replaces it.
We don't want to replace the file we want to open it, stick a new line on the end and then close it.
So the thing we put here is a for append again the encoding is utf-8 as it's going to be an output stream so we say fout.
Now, we haven't really worked with this fout thing we've just been passing it off right hey JOSN go read or write from this that's what we've been doing but this has some cool features.
We can say read, which reads a character.
We can read line, which will read one line from the file.
We can read all the lines, which'll load the whole file and memory.
None of these are going to work because we don't have an r we have an a.
But we can write, we can write things or we can write one piece of text or we can write a whole line.
So what we want to write is, we want to write maybe the message.
Now if I run this something weird is going to happen.
The message is going to pile up, one after another after another on the end.
The out on one gigantic ginormous line so we have to do another thing to say and add a new line, right.
Add a, a line break and in most programming languages it's kind of weird, you have this way of saying escape characters or special characters you say backslash, it's not a real backslash that's the next thing that comes is a signal.
You say \n, so \n means new line, like enter.
If you want a backslash you need two backslashes, there.
So that was going to add a line we need to close and flush this file stream but that automatically happens here.
Okay this is a good start, let's just see what we got.
Run it, notice the not really is gone.
Lets see Hannah's coming back in to try another round, she's going to throw a lot of sponge this time.
Got beat with a sponge, just gettin' burnt ah man crushed right away, as the computer is apt to do.
So let's check in and see what's over here now.
Look at this, rock, paper, scissors, log and we open it up and check this out the app starts up, we've loaded this so that goes there, has us logged in.
New game, look that's so cool.
So here if I just do it one more time.
If I'm Michael, I'm just going to throw air at this computer, see how it likes it.
It's it's liking it, man that computer is rough!
But notice down here now that we have the Michael round appended on, isn't that cool?
Right well, super, super cool I think.
Let's do one more fun thing.
Let's come over here and copy this path the entire path, go down here.
We can tail, -n, let's say N for history and -f this.
Now you can see what's already there but I'll clear out the screen that's still running I didn't stop it, it's just hanging out there.
Let's put this over here this, and lets just run one more game.
I'm going to give Hannah a chance to pull- Look at that!
The computer's ten to four against all of us.
But look on the left, the app has started up we've opened up those roles, cool.
User two is logged in that's not what we want let's try that again.
Hannah, Hannah's logged in look at it just showing what's happening as its going.
This is going to the files, super cool.
We're going to just throw fire the whole time.
All right, Hannah takes the round, high.
Computer takes the round, Hannah's doing again, high.
Whoa look at that, Hannah won the game and she's now ahead.
We'd run it again, I'm going to say Michael you can see the log files just rolling along with it.
One thing that would be nice is if we're back here looking at this log file to know, hey this happened yesterday, or five minutes ago or these two things were separated by ten seconds or something like that right?
That needs some extra information that's not up to whoever's calling log, here, we add it on.
So what we can do is we can use a little bit of formatting here we can say, refix I guess we could call it.
Going to be a little f-string and lets go over here and just put a little bracket and we'll put the time in.
What we want to use is datetime remember that from one of your exercises?
Normally it'll let us import it but maybe not inside of an f-string there we go.
So we want to import this one, the module not the class and use it over here now.
Say date time, dot datetime.now.
When we run this it's going to have a whole bunch of stuff that we don't want, so we just want isoformat.
Like this, this'll be a simple version.
And we're going to, let's just say instead of calling it a refix, we'll just write that bit.
Here we go.
Let's run it again, ah put it on the side our hail is still running over here, that's cool.
Our name is Michael, there we go for some reason that wasn't scrolling I'm going to throw some more fire.
Look at that how it has the time well maybe it's a little bit too precise you know maybe we should trim that back.
We could obviously come up with that.
Maybe we just care about the day.
Probably not actually what you want you probably do want the time.
But if you want to bring this back we could say today iso run it again and whoops not today sorry just date, just the date part.
There we go now you can see there's the date right there.
So my name is, I'll give Hannah one more chance.
She's pulling ahead, throwing a lot of water look at that she's taken around, look at that.
She crushed that computer, showed them.
But here you can see, if you want to have just the date you can do that, or you can do this.
The point is not to re-create logging actually this is built into a lot of systems and you wouldn't really do this.
It's more to teach you about how to work with these text files.
Use the file stream, write text to it and then create new lines and add append to it.
And that's what we're doing, it looks like it's working really well right?
|
|
show
|
1:26 |
Let's just quickly review our simple little log thing.
Where we were able to write out some kind of message and append it to a text file that is just line by line interesting.
So we wrote this log function it takes some kind of text and we use our os path to come up with the absolute path.
And then we come up with some form of time text.
Here we're using this string format time.
Which gives us actually, a better output than what I was doing.
Then, we're just going to use our open method inside of a width block get a output file stream out.
I name it so it reminds me yes you can write this but not read from it or read from it, but not write to it based on how you opened it.
Cause the functions are there for both.
But depending how you open it one of the other is available.
But the most important thing here is that we used a to append rather than w to overwrite.
And then we just write out parts of text and it piles up all in one line so we'd write the time text then we'd write out the message that they're actually trying to log.
So they don't have to worry about the timing.
And then we say that's the end of this line wrap it around, so that the next time we try to log to it it starts on a line below.
And that's it.
And here we're also printing the message.
So you can both log to it everything that goes to the screen, basically will also go to the file.
If you wanted.
We did ours a little bit different in the demo.
Not too hard, it reuses a lot of the same ideas.
But very very cool, and quite easy to do.
|
|
show
|
1:14 |
I want to just emphasize, do not do this for actual logging, use a loggin framework.
So, I showed you that example before about our file syncing things across the different video servers it's using this thing called Logbook.
And Logbook is super cool what you do is you create an instance of it and then you say log.info or log.notice, or log.error and then you can set it at a level so I only want to see warnings and errors or I want to see notice, warnings, and errors or I want to see everything.
Show me all the messages depending on what you're doing with your application.
And it automatically adds the time it automatically rotates the file name for the date so you know it has, like if you said rps.log it would be RPS log dash whatever the year, month, day is.
It's actually really handy cause these files can get really out of control and you usually want to know kind of on this day or that day, what happened.
It also puts the messages about the level of the message and the origin of the message.
This is way better, way more tested than something that you're going to create.
And remember the login was more to teach you about writing and appending the text files than it was to actually create a login system.
So use a real one if you're actually going to do that but this ideas you learn from the login example are absolutely applicable to all sorts of files that you might work with.
|
|
show
|
1:51 |
Well that's enough reading and writing files for me.
It's time for you to read and write to some files yourself.
So you're going to do some similar things that we've done here, work with JSON files work with lines of texts and plain text files.
Let's go see what I got on deck for you.
Over here in chapter nine working with files you've got the standard introduction threw in a few concepts for you, determining the full path of a file using os.path, reading a file using with open file name r, write in to a file make it a w, working with a JSON, import this loading from and writing to various files and finally, the exercises that you're going to do are going to be going back to the games that we created.
So, the Tic Tac Toe game from back in CH08 the one about problem solving at least whatever number that turns out to be at the end of this course, and work with that.
If you happen to have gotten all the way through the previous chapters exercises and you did build Connect Four, that one's yours.
Go ahead and use that instead.
The idea, we'll work with either of them.
What we are going to do is just create a leaderboard.
Use JSON format if you like.
That works out really easy so that's what we did.
So a leaderboard, create that, and update it as you win and play.
Then add a running log file.
This can just be appending to a text file nothing about it fancy, logging frameworks and just do that.
That will help you practice appending to text files.
That'll be great.
If you want to, and you get to the end and you want to try it out, you could use Logbook.
It's going to cover some of the topics we cover in the external libraries package as well.
So, you don't have to do it now but if you're feeling ambitious feel free to go though their quick start and give it a shot.
If it doesn't work, don't worry.
We'll talk about more of it for the next chapter.
But this is a really cool library that helps you do logging the right way and it's what we use and it's been working great for years.
Alright, get out there and have some fun adding file IL to the games that you built.
|
|
|
39:44 |
|
show
|
2:10 |
So far we've done really cool things with Python, but the world of possibilities is about to explode with what you can do with Python.
In this chapter we're going to talk about working with external libraries, or external packages as they're usually referred to in Python.
Remember that graph I showed you the incredible growth of Python, how it's taking off?
That's because people are finding Python capable of doing so many things.
And yes, what we've seen so far is pretty awesome the language and some of the standard library, things like os.path and JSON and so on, are very very powerful.
But they are dwarfed by these external libraries that you can use.
There are so, so many of them.
So let's start this chapter with a bit of a comic that tells that story.
Here we are back in our terminal.
And if we just go and run Python3 we're back in our REPL, right?
Remember this?
Hello, world.
Well, the way we use libraries in Python is we say import remember, import json, import os and then we could do json.load, or whatever it was.
Well, there's this XKCD comic that says there's so many awesome things that you can import mostly talking to the external libraries, but also the stuff built in that they said you can even import anti-gravity.
Check this out.
You import anti-gravity.
I type this, it launches this XKCD comic and it's about Python.
So check this out, there's this guy he says his friend is up there.
And this guy was, How are you flying?.
The guys is, Python.
I learned it last night.
Everything's so simple.
Hello World is just print.
Hello world.
I don't know.
Dynamic typing in white space?.
Come join us, programming is fun again It's a whole new world up here.
But how are you flying?.
I just typed import anti-gravity.
That's it?.
Yeah, I also sampled everything in the medicine cabinet for comparison, but I think this is the Python.
Anyway, this is really cool.
And it's a joke that just touches on how many things there are at your fingertips if you wanted to start working with these external libraries.
And that's what we're going to do in this chapter we're going to work with a couple of these libraries that are super awesome, they're going to enhance our game even further, and you'll see just how easy it is to work with them.
|
|
show
|
2:23 |
When you want to work with an external library stuff that doesn't come prepackaged with Python the best place to start is pypi.org.
This is the Python Package Index.
And here you can see when I took this screenshot it was 206,000 projects.
That wasn't very long ago and it's already over 215,000 projects available.
These are 215,000 external libraries.
Each of which, maybe does something really awesome.
Some of them are web frameworks others are graphing libraries others still are maybe genetics libraries that'll process well known genetics file shown common applications and do analysis on them for you.
There is just this huge variety of what is here and we talked briefly about this at the practice section of the last chapter.
But just in case you didn't see that one Python's Package Index, PyPI is where we're going to go to get these external libraries that we're going to work with.
You can install them outside of this place like directly off of GitHub and stuff but this is really nice because the built in tools look here if there's an update it will automatically grab it and upgrade it for you if you ask it to.
Stuff like that.
The big challenge of this is it's something like the paradox of choice or the cursed of abundance I don't know whatever you want to call it here.
If you go and type in like web crawling there's 10,000 plus results.
How do you know which one of those 10,000 is popular and which one you want to use?
I don't think PyPI actually ranks stuff by popularity when it shows the results.
So that's kind of unfortunate.
So anyway, how do you narrow this down?
Well there's a lot of ways.
One of the options, if it has the right category for you is to use something called awesomePython.com.
You can come over here and see the table of contents on the right.
If you're doing, I don't know, caching or authentication or audio work or whatever it is you can click on one of those categories and here it'll show you a big long list of the popular and recommended projects from that category.
There might be 500 admin panels but there might be only 10 listed here.
The way they get on here is they have to be pretty highly used and recommended by multiple people, things like that.
So this will help you narrow it down in the case that they have a category for it.
If they don't, then, you know have to just search the internet and see what people are recommending for the packages.
But there are some many packages and using them in Python it's totally easy.
|
|
show
|
1:26 |
Our game is okay, but boy could it use some color or some UI or something, right?
It all just blends together.
It would be much, much nicer if we could quickly indicate who's playing what, whether or not you've won, and so on.
So what we can do, is we can use an external library that will make it very easy for us to output color instead of regular lain text.
You can do it without these libraries, but it's complicated, it's different across different operating systems.
With these cool external libraries, you just basically say print, but make it blue, or print, but make it yellow, and then out it comes.
So this is actually going to be a big improvement to our app, and we're going to get a library called Colorama that let's us do this.
But, we could go a little farther.
We could come in here and we could say, in addition to color, it's one thing to have that great long list of one, two, three, four, five, but what about a little dropdown in our terminal here?
That'd be really cool, right?
And it can autocomplete, so if we typed S, it'll pull up scissors and sponge in our final example.
Even if we typed, I don't know, R, it would pull up rock, and scissors, and I guess paper, as well.
But, you know, if you type enough that it's going to narrow it down, then it'll pull those up.
Like if you hit C, it would be rock and scissors.
So, we're going to be able to add that little UI using a different library and combine these two, and you'll see that it's easy to do.
We basically say their name, we ask Python to go get them for us, and then we can just start working with these extra libraries.
It's going to be really fun.
|
|
show
|
5:40 |
The first thing that we have to do to get started with these external packages is to set up a place where can install them and manage them.
Now, this is really easy, but it's not entirely obvious.
So, let me just tell you a little bit of background and give you an example about why we're doing this before we go down this path, when you're working with these external libraries, they have versions.
And these versions change over time ideally as they go forward in time they're always able to run older code that was written on them, but this is not always the case.
Sometimes, a version one of the library won't run stuff that was written against version .5.
If you're working on two projects on your computer and let's say they both use the Flask web framework one has to you 1.1, another has to use 0.2 and they're not compatible, how are you going to install the same library with two versions?
You can't and it turns out that you also want to maybe know what are all the packages I'm using for this project by itself, not that I've happened to install for other projects, as well.
So, because of that, Python has this thing called Virtual Environments, these are like little isolated copies of Python that let you install and manage it separately, so it's isolated.
Now, the way we do this is pretty easy but let me put you at a quick article here this one at snarky.ca, this is Brett Cannon he's one of the core developers on Python and he talks about a Quick-and-Dirty Guide on How to Install Packages for Python talks about these virtual environments gives you some examples, so you might want to check that out for more reading, but let's just get started.
I want to go to this folder here.
This is our folder 10 for our Get Help Repository.
I got this cool little plug-in or extension for our finder here called Go to Shell I think Windows has something like Go to Command Prompt or Power Tool or something like that I'm not sure what the best way on Windows is to do the same thing but you can always just CD over there.
So, in here where our files and what not are we're going to run a command that will tell Python to make a little copy of itself.
And it has this library called pip pip is how we install and manage these external systems and external libraries, but one of the things you can do is say, pip list, and here's a whole bunch of stuff that somehow got installed into my computer but I don't want those, I want it separate little tiny isolated one, so what I'm going to do is I'm going to say, Python3 -m for run a module.
venv the name of the module is virtual environment.
venv then I'm going to give it a folder which I also by convention call venv.
That's a little bit annoying that it kind of looks like that or unclear I don't know but it's fine you'll get used to it.
So that's going to take a moment.
And then if you take a look here there's a folder called venv and if we look in there there's a bin, and if we look in bin, you can see there's hey a little Python and then there's a little pip and so on.
But what we care about is activate activate right there.
So on Windows this is scripts not bin but otherwise it's basically the same.
To make this active what we have to do in the Shell is we have to say dot space or you can say source space.
One of those, either those are fine on macOS and on Linux on windows just don't put anything.
I'll show you the Windows command in a second.
We say venv/bin/activate.
Now see my prompt here?
It gets this in here now if I say pip list it's just those two.
And it's kind of annoying but it always installs a version that it came with not the lastest version.
So you usually want to run that little command now if we ask for pip list then we get that.
Cool.
So on macOS and Linux you say this and on Windows you say, you get the dot, you just say venv\script\activate which is activate dot that.
And that will have the same effect.
So now we've got this little isolated version of Python and we can install things in here.
So right now as you saw we have our pip list.
Just as these two.
But we're going to use the colorama library.
We can install that PyCharm or we can install that here.
I'll do one library here and one library in PyCharm.
So we can say pip install colorama.
The library that lets us add color output.
And now if we ask for pip list.
You can see colorama is installed as well.
Okay great.
So now we're ready to get going with this environment and this program so I'm going to put that actually it's already ready over here let's load this up in PyCharm.
Now one thing that can happen over here is the project interpreter it might not have detected this.
Sometimes it does sometimes it doesn't.
So you can see whether or not you can choose an exisiting one and browse over to it and so on.
But you want to go and click add if it doesn't already find it because it selected it, it wasn't in the list.
So here you can see colorama, pip, and, so on.
You can even add stuff through PyCharm here, I can add request with a common library, or I can click the install or if there's an update I can hit like here this one has an update, okay hit that little up that and we give it a second.
Move over to this side.
Didn't mean to click that up sorry.
Right here it's doing something now it was updated.
Cool.
So that's a nice visual way to manage that stuff as well.
One thing you want to do with these virtual environments is make sure they're ignored.
See how they're like grayed out?
Whatever.
Okay great.
Alright so we're now ready to use this library we can come down here and we can say import colorama and because we pip installed it into our virtual environment, the virtual environment you can see down here, is active right there.
That means that we can use this library and PyCharm won't give us an error it knows about it and we can start programming against it.
|
|
show
|
2:48 |
Now that we've got our virtual environment here we're ready to use colorama there's still one more step that we should take.
There's nothing requiring us to take this at the moment but in the future you're going to be really glad that you did.
So, one of the things that's important is for us to express to other automated systems other developers or users who get this code and want to run it, that this code now is going to require colorama.
If we don't have colorama installed and we run it what's going to happen?
It's going to crash and say we don't know what colorama means.
So in order for us to make that clear like this program must have colorama or whatever other external package is installed there's a convention that all the tooling understands.
Come over here and add a new blank file called requirements.txt.
And down here all we have to do is put the same command we would type to pip install whatever into this file we just put the whatever.
So in this case we just put colorama.
Notice that PyCharm is saying there's a thing we need you to install called Colouram, well no that's not true and once we put colorama it's good.
This squiggly, just PyCharm thinks it's misspelled which is weird, but if we also depended upon requests we could have it like that and if we click this button it's the same as if we went and activated the virtual environment and said pip install request but we're not actually going to do that here.
Let's go and just see how we might add another library that we're not going to use yet but we're going to use eventually this thing called prompt_toolkit.
Now if we go down here to the terminal it should have the virtual environment activated.
You can double check by saying which or where Python and it's going to be the one in that folder, if it's right.
So if we come down here and say pip list you can see here's colorama, but not prompt_toolkit.
Also if you go to this UI bit here's colorama but not prompt_toolkit.
All we do is click this, PyCharm knows, hey I told you the tooling understands requirements.txt it knows that this means something if we click it, it's going to go and say hey that got installed okay.
If we go back to the UI look here now prompt_toolkit is installed similarly if we look at it this way we say pip list, we now have prompt_toolkit.
We're not using that yet but those are the two we're going to need so I put them into our requirements file, right here.
That's cool, right?
So we've got this requirements file that any time you get this code out and you want to run it you just can say actually there's a way to say install everything I need from here as well as pip install dash R, or our requirements file requirements.txt and it tries to install all the things.
We saw that's basically what PyCharm did it looked and said there's some stuff that's missing click this button and I'll run that command for you.
That's the requirements.txt and you should always have one any time you're using an external package.
|
|
show
|
7:34 |
It's time to start using our Colorama.
Lets go and run this really quick.
Here you can see we've got rock, paper, scissors version here's the header.
Maybe we want the header to be like a cool pink or something like that.
And yet here it's just gray.
Maybe we also want to ensure that the background or the default color is white.
For example, if I come over to my prompts my terminal here you can see that my normal colors are yellow.
And if I were to type Python3 everything's yellow.
So for example, if I run this program I copy this from there.
I'm going to make sure I use the Python from that virtual environment to run this file.
Everything is now yellow.
It'd be nice to have a baseline color for what we're doing here.
So what we can do in the beginning is we can just start, right at the top of the file.
We can just print out some kind of text or something using Colorama to make it that color.
So the way we do it is say colorama.
or dot, and then whatever color we want.
Let's go with white.
Now if I do this over here and run it see everything's yellow.
But as soon as I run it it's turned everything white.
And as we work with it, it's just going to stay white.
For now, okay?
The program exits then it resets.
So this kind of does a baseline color for us and what else do we want to do?
Let's go over here, I'm going to copy this.
I'm going to use it a lot.
I said we want to have the header have a color, right?
Let's go over here and say print or dot.
What do we want here?
Magenta, maybe?
Magenta's going to be good enough.
Now we can do it like this.
We can come down here and say that plus text but this is so big I'm just going to put it like this.
And we want all the stuff to be here.
And then we got to put it back, colorama.Fore.WHITE.
Okay, well one thing that we're doing a lot of is saying colorama.Fore.that.
Now here, normally I like this format.
I like this format because it's really clear where all this comes from.
But we're going to be combine it with a lot of text so we can do it, import a different way.
Let's roll this back a little bit.
Notice there's an error.
We come over here and say, From colorama import, the stuff that's in there which is all those things.
And just say for, that arrow goes away.
If you don't type this by the way PyCharm knows that you should have typed it so we go over here and we can hit Alt + Enter and it says, Do you want to import this?
You want colorama.Fore?
Yes I do, and it'll just write that line as if we had done it up there.
All right, so that's a lot of talking.
Let's see what we're getting here.
this up and try it again.
Check it out.
We have our color version up here of our external libraries not really sure that I'm digging this V2 thing so let's do it like that.
Cool, Rock, Paper, Scissors, this edition then if I type this we're not quite seeing anything yet are we?
So let's go back up to the top.
Our player's logged in.
The log, it goes to a file.
It doesn't make any sense, I tried to make it color it won't respect that anyway.
So the next thing to do is let's go over here, let's go down here let's, for all the errors, give them a color, huh?
Come down here and say Fore.LIGHTRED or RED.
There we go.
So let's go and see if we can get a color here that's not so good or a output that's not so good.
So my name is Michael, I want 99, try again.
Notice we didn't reset it.
So let's see, we could do that.
Fore.WHITE again.
There's some cool coding techniques and stuff that we could use little data structures that we could come up with to have that automatically reset but for now let's do it like this.
It's going to be Michael and 99, try again.
See how easy this is?
For us to see what's happening?
Okay, let's see.
For the round we're going to roll these things.
player_1 rolls this.
Let's make it really clear who's rolled what so for you the player what are we going to use?
Let's go with some yellow.
For your opponent let's have a light blue and then let's reset it like that.
Keep going.
And by the way, I'm running because it's more clear, the color stands out more but you can run it in PyCharm and see those colors.
You see them down here for example.
Do 99.
It comes up but it's not quite as clear because the gray background.
So let's go and keep running up here.
Michael, 99, no, let's play again.
I'm going to throw some sponge, love some sponge.
Michael rolls, roll sponge?
Computer roll scissors.
This should really stand out here.
Who takes the round maybe even the scores here we could do some work.
Fix the S, and here we can put we don't want to log that for thing so we want to put that here on this output.
We could do this we could even say something like this we could say four equals the four there.
I could say this if winner equal to player_1 else that means you've lost so Fore.RED, light red, something like that.
Let's try that here, I think that'll be fun.
So come down here, I'm going to be Michael.
I'm going to throw some scissors oh, we didn't put it back, did we?
Look, I won the round!
We could do it like this.
White and the same message there, that should do it.
Okay, try again.
Michael, throw some sponge.
Computer takes the round I'm going to throw some air, some more air aw man, that computer is tough.
Let's try two, three, three, it was tied.
Computer takes the round.
I'm telling you, this computer has got my number I cannot beat this thing.
Seven, two, yes!
I've taken a round!
Remember it was kind of hard to scan this you had to read over it, What's going on?
and so on.
We're also going to improve this so it doesn't take up so much space later but for now we're getting our color there and then, yeah, we're pretty much done.
Let's do one more thing here for this color here.
Let's put, yeah we don't need to do it.
We could print out some stuff but we'll keep it there.
Again we'll say Fore equals let's get the same little test here.
If overall winner is that and then we just want to do Fore plus.
And let's reset it, Fore.WHITE.
Actually, careful, we don't want to log that.
Not sure what'll happen if we put that in the text file but it's probably isn't good.
So here, let's play one more round take it all the way through.
Michael, I'm going to play some sponge because that's my favorite one.
They played scissors which cuts the sponge aw man, I cannot win.
All right, I took a round with some rock do some more rock.
Getting close, yes!
I take the round, and I win the game, incredible!
But down here we have that coming out of the bottom.
Hopefully you get the sense that just this little bit of extra color really makes this game easier to play and I think a little more entertaining as well and it was all made possible by Colorama.
So Colorama is this public thing out on the internet we're able to download it and install it with pip into our virtual environment here.
Even expand it and probably see somewhere the packages are installed.
Yeah, there's Colorama toolkit and others.
But you don't mess with that, you just leave that alone alright?
Same thing over here.
packages, we don't want to mess with these but you can see that they're there.
The best way though is to go over here and say pip list and it'll show you what's installed what version and so on.
Alright!
Very cool, we made our app better by using one of these external libraries.
Well that's a start.
We used one.
There's 215,000 plus more to go explore see what cool stuff we can do.
|
|
show
|
6:20 |
We have a nice, colorful game.
It communicates a lot back to our players but they still have to pick one, two three, four, five, six, and it will be better more natural if you said, I want to play air type a, enter, and you got that or I want to play rock, type r, enter and go and have this auto-complete thing that we saw in our example before.
So up at the top, we're going to start using r, prompt_toolkit.
Now we actually want to get a couple things We'll just say from prompt_toolkit import prompt.
You're going to read the docs about how prompt_toolkit works to see how this is, and we also need another thing to get the completion to work, so prompt_tollkit.completion word completer, is what we're going to use.
So this will do the prompt and this will actually show the little completion thing.
Now, as we've broken our program into these functions it turns out, it's really nice, you go over to this play game, remember, we already have this function get role for our players.
If we just go here, and look at that this function already knows how to talk to the user, validate it and those kinds of things.
So what we can do, is we can actually Oh maybe I'll leave a copy of this here for you, open it out.
We can go and change this to actually show something different.
We're going to just change it to use the prompt_toolkit and that'll be great, it'll just upgrade it and no other part of our program has to change.
So let's change how we're showing this here.
We can do a little printout there and we can printout the role names just directly, like watch this Just change that little bit for now.
If we run this, 'My name is Michael,' I get the typing in the right place Come here thing!
If I type it right there you can see it prints this out with the brackets and the quotes.
It's okay, but it turns out there's a really simple thing we can do to make this better.
We can come over here, and strings like just this this comma right here, has a cool function and we can say join and given any other set of stings it'll put them all together and just separate them by whatever's here.
If you had a dash, it would be dashes.
If you put a comma it's that.
You put a space, it's comma space and now if we run it you're going to see we have this nice, little description.
So that'll let them know what to type there and we're not going to ask them, this way anymore we're going to ask them with the prompt.
So we're going to say prompt Oh look at that, completion information up there.
So we're going to come here and we're going to give it the name, player name.
What is your role?
Something like that, you know we also need to give it one of these completers.
So we can come here and say, completer equals and let's come up with something like that and we've got to create one of these things and this is the word completer that we came up with and it's really cool.
All you have to do is give it a list of words it can work with.
Well, what are the words we want?
Role names, that's it!
How cool is that?
But this is going to come back with the role.
It's going to be this, and now our test is going to be different.
When I say if not role, they didn't give us anything, or role not in role names.
We're going to go like this It's not valid or something like that.
Not valid.
And here we can just return, role.
Well, I think that does it!
We were able to change from this built-in input to this completion one.
Let's see how it works.
Now, it turns out, this does not work inside of PyCharm.
This little run thing that's down here this is not a real terminal or command prompt and so the interaction's just not going to work.
So that way, you have to run it over here like this.
There's a way I figured out how to run it is I clicked run here, and then I went up and I just copied this whole bit in the top and pasted it into the terminal and command prompt.
So we do that, right here.
My name is Michael, fingers crossed I want to play scissors.
Oh my gosh, look how awesome that is!
Scissors, we can do sponge.
I can do stuff like air, paper.
Now, what I'd like to be able to do is have stuff like, if I type R also have that pull up water and air because it has it in there.
You can debate whether or not you just want to have the stuff where it starts but here we can pick sponge sponge works if I put junk.
Sorry, that's not valid, try again.
How about sponge again, my favorite.
Of course the computer beat me but that's fine.
This is cool right?
This is working really well and yeah, it gives us basically auto-completion on all of the words that we pass to it...
down here.
Anything in that list, it has to start from the beginning, so it's kind of you got to type it in it'll complete it it won't give you sub-names.
The word completer will just complete whatever you type of any array of text or list of text words that you put in here and that's how we add it.
We just call prompt, give it the message and give it this completer to have it show it as we go.
One final thing though if we'd run it here, and I try to run it like this notice warning warning, output is not a terminal my role is, I guess rock, it sort of still works but you can see this is not good.
So let me just throw in a little check here.
Remember, I told you this doesn't work in PyCharm.
So what we can do is say when PyCharm runs our program it's sets an environment variable called PyCharm hosted to one and we can check, are you running in PyCharm and if that's the case what we're going to do is we're going to give a little warning and then just ask.
So now if I run it, it kind of falls back to the old way.
Warning, fancy prompt doesn't work run it outside to see it in action.
What's you role, it's rock.
Oh, yeah, the reason that crashed is that I typed capital Rock course I've got to type lower case rock.
There we go...perfect..
The validation is not in that part.
We really don't mean to play this version that way we are meant to play it this way.
Notice, no warning.
My play is...
sponge.
There we go...
Perfect!
So, everything's working great with our basic version here.
Turns out we can do a little bit better but we've already gotten quite a benefit from having this and let's clean that up.
Here we go.
Love it!
|
|
show
|
9:07 |
We have our game working pretty well it's running again over here.
Remember to get the completer to work the drop down thing, it has to be over here in your terminal or command prompt.
Your name and then we can type r, we can type s.
Couple of things that would be nice; The selection of which one you've selected is not as obvious as I would like.
Is it sponge or is it scissors?
Without looking at the line above well, I don't really know because they kind of both look selected in some way.
Guess if there were more, it'd be obvious.
Also, I would like to be able to not have to start typing.
I would like to be able to use this little drop-down and just hit Dot and have it show me all of them.
I would also like to be able to type just anything with an o or r and have that pull it up.
Like Air, Water, Fire and Rock.
Pretty much almost all- That's all of them but, some of the sub-letters are sub-word matching, right?
So if it was like, Fire Rock and you just wanted to type Rock and get it to work that's what we're going to add here.
So this is pretty good, and what we need to do to make that happen is we need to make another one of these completers.
Now, the way we're going to build this uses a concept we haven't yet talked about in Python.
So, what we're going to do is we're going to have to create a class.
Class is something from the object oriented side of programming of Python and it's a way to bundle both data and behavior together.
You'll want to create a class don't worry too much about the details.
Later class courses go into object oriented programming and whatnot but this is pretty basic so I'm sure you can follow along.
We're going to create this thing called a PlayCompleter, and this name we make up.
Just like we called this file name and we called that directory here, we called that We can call that whatever we want but it has to be based on this completer thing here.
And completer comes from the prompt_toolkit.
So it's like a foundational information there.
And then we're going to give this the function get_completions, and it takes all of this stuff.
Really cool that it has these type annotations but I'm going to just take them out for now.
Keep it simple, 'cause we don't technically need them.
Here we go, now what do we do with Let's put put this up here.
Our job to extend or customize this prompt tool kit library is going to pass in basically the terminal as it is and what it's trying to work with.
And then we're going to be able to say well gimme the word.
and then here's what we've computed the recommendations for what the dropdown should be.
The first thing we're going to need to know is the roll names and this has to be a list so when I go to the rolls the keys convert that into a list.
Remember that roll.keys is like a list you can go through it but it's not technically a list and so it's a dictionary key collection or something.
So we got to do this or it won't work.
The word, we're going to get that from the document.
You know there's nothing totally discoverable about this to tell you what you need to do but if you go to the documentation you want to get word before a cursor.
Like that, and that's what they've typed.
So if they type ai and they want Air completed what we're going to get for word is ai.
Then we might want to complete all of them if there's no word here.
Or if they type dot, I want to be able to type dot and just have the dropdown drop down.
So that's what we're going to do right here and save not word.
So our first case is if there's nothing typed we're going to make sure that something is here.
We're going to type word equals dot.
So, if there's a word we're not going to Complete All otherwise we're going to just check and see if it's a dot.
Then we need to store up the completions.
So these are the actual words that match that we want to work with.
So, a lot of setting the stage and then what we're going to do is going to say for roll in roll_names.
If we're going to Complete All then we want to go to Completions and Append roll.
So what's happening here is we're going to go through all of these and say if it's like something we want to show all of them just through every one and put it in a list, okay?
We can also do another test here or if the word is in the roll.
So this is the sub word like ai and here are the rolls Air, so we want to put Air in.
But if it's Rock, where it is not ai is not in rock so we're not going to put it in the list of completions.
So either we want to put them all there our word is sub string of the roll the word that we're looking for and trying to complete, and then we're going to add it there.
Now it would be nice to just let's go ahead and say Return Completions.
That's really all that we have to do.
However, for the completion to work it's not enough to put just the string here.
We have to put this thing called a Completion.
Completion, import that from prompt_toolkit and this takes extra information.
While the text is going to be roll.
Let's wrap this around so we can see a little bit better.
I see the start position.
I'm going to go back and basically erase what they've typed.
If they type ai we're going to go back two, and overwrite ai.
We're going to set a style, this is like the color and whatnot.
Set the foreground to white and the background to dark green.
And that's not misspelled, not really.
And then we save the selected style going to be something like this but not exactly.
The yellow and green.
You can play around with these and see what they look like, and if you like them.
Okay well, that probably is a little bit complicated but it's just going through the documentation for how this prompt_toolkit works.
Let's run through it again.
We're given basically the terminal we say Alright, we need all the names that we could complete.' We're going to get the word, whatever they've typed.
We need to compute do we just put everything in there?
This is the little test for that.
Then we got to bundle up all the stuff that we say These are the words I want you to show in the dropdown.' go through all the possible names and either add them all or, this is our other test is it a sub string?
If that's true, we're going to create one of these completion objects, put it in the list and give them back.
All right, let's go and try to use this thing up here where we did our word completer before.
We had this, now all we got to do is change that, and that.
And if we did everything right, that should work, right?
So what we usually pass the completer this library asks this little class, this object Hey, here's some words.
This is what they've typed what do you want to do?
How do we complete that?' Well, let's give it a shot.
Remember, we cannot run it in here it's just going to go back to the old brain input.
Got to run it out here.
All right, fingers crossed!
Micheal, my roll is Watch if I hit dot, yes!
It'll pick scissors, see how cool that is?
And look how obvious which one is selected it even matches the background color of what's shown there.
So, let's throw some sponge, yes!
Now if I type o, look at that.
Rock, scissors, sponge.
If I type space, that's where it's not the word the strip thing, and we can do that as well.
So if you just hit space you get this if you hit dot you get this.
Or if you type something like s or r well R is a little bit too much.
E, here's all of the things that have e in it how cool is that?
Incredibly simple.
Throw some water into it.
Water, oops got to still select it.
Boom, water.
Do it again, you know what?
We're going to finish this out with some fire!
Take the round, finally yes!
Phase through the sponge, burnt that thing up game over, Micheal takes the game.
How awesome, so I really really love the way this is working.
It's not huge advanced user interface but it is much better than what we had before.
So all we had to do is extend this a little bit pass it over here to this prompt_toolkit.
Here's the class that we wrote.
It just derives from completer which means it takes some of that information and then has this little bit of extra.
We're going to go down here.
I guess we could probably make this clearer if we use some variable names.
I could say Let's do it like this.
It's sub string.
That'll either complete them all or if it's a sub string and then here, this.
And completion is okay.
Here we go, either you complete them all or it's a sub string.
And if it's a sub string, either way we're going to create one of these completions pieces and then add it to our list and we're trying to make sure it's going to work again.
Not going to be able to find out there, are we?
Dot, works like a champ, awesome.
Well, there it is, we've taken two external packages.
Up here at the top, you can see them.
Colorama and prompt_toolkit and we started working with all the capabilities and features they provide for us.
And we got a much better game and we had to know very, very little about working with the colors, working with the terminal stuff.
Whatever is involved in there.
To do the dropdown and all that all we got to do work with the simple APIs from these public pre-opened sourced packages.
It's great.
|
|
show
|
1:15 |
Let's take just a moment and review how we're using our external libraries or external packages.
We have a requirements.txt where in our program we express this program is going to need these external packages or it's going to crash or not run or it just won't function.
So we put that in the requirements.txt somewhere and then before we install the packages you want to make sure you have an isolated virtual environment.
So you do that one of two ways depending on the operating system you're on.
A macOS and Linux you have this Python3 -m venv that's the module, the command and then venv is the directory you can change that to be whatever you want.
Then you have to say .
foldername/bin/activate.
On a Windows very similar but it's no dot, and then venv\scripts\activate.
Once either of those are done your prompt should change to have this little venv or maybe in the future the folder name at the top there.
And then you just pip install the requirements by saying -r and then the requirements file.
It doesn't have to be requirements.txt but it probably should because that's what the tools look for.
Then you can just start using your library and import colorama, work with its elements like this four class or four enumeration.
Here we want to say hi, with color.
Make that green?
Easy now.
|
|
show
|
1:01 |
It's time to work with external packages yourself.
We're going to do something similar for the practice exercises as you saw me do in this video.
Over here in the GitHub Repository we have our practice exercises for external packages couple of concepts, working with requirements.txt virtual environments, how to do it on the various operating systems, working with pip and once you get all those all of those down you should be good to go.
Your goal in this one is going to either work with the old tic tac toe game or the Connect 4 game.
And basically what you're going to do is you're going to use Colorama to add colored output to the game, and the steps will be create a a virtual environment make sure that Python is the that it's the right active interpreter and make sure you set that virtual environment as the active interpreter.
Use requirements.txt to specify you depend upon Colorama.
Install those requirements with pip or with PyCharm.
It detects it and suggests them and then use colorama.four.green and so on to add colored output to your game.
|
|
|
23:22 |
|
show
|
1:40 |
Well I hope you're proud of the little programs that we created are rock paper scissors and tic tac toe and all the other things.
And they're pretty good but there's something that we've been overlooking so far.
And the reason they've been over looking it is I've been trying to focus on the core programming concepts.
But no program is done until it is handling bad user input or other types of situations that it didn't expect.
Here we are now rock paper scissors game and we have a new player crash bandit, uh-oh.
Well it says please enter a number which one would you like?
1 through 7, I said, Cool, we'll take 7.
s-e-v-e-n, enter.
Boom!
Our program exploded, it's done.
It didn't just report that it couldn't understand seven.
It said, We've crashed so badly, we cannot continue.
I can see the process finished with exec code 1.
That might sound good, 0 is good, non-zero is bad.
See it says there's a ValueError input literal for int, we can't, it's invalid we can't take the word seven, we need the number 7.
You know the purpose is to take quote, the num the numeral 7 and turn it to literally the integer seven.
And it can't take it this way.
Maybe you would expect it could, but it can't.
So that's a problem, what we need to do is say Hey, we saw that you typed in something wrong no worries, we got you, that was invalid why don't you try something like one through seven as a numeral.
So that's what were going to focus on in this chapter.
Were going to keep it pretty short and tight.
But there are some essential error handling things we have not touched on, at all.
And it's going to allow us to catch these errors stop them, figure out what went wrong tell the user what the problem was and potentially let them keep on going.
|
|
show
|
2:23 |
Well, let's fix this crashing program that we've got going on here.
Notice we're over in error handling, rps error handling.
This is in CH11 in the GitHub repository.
And I've already sort of set this up a little bit for us.
We've got the rpsgame, and it should look really familiar.
Except for there's a few issues we're going to solve that in a second but this starts up and it's going to say Oh, not external libraries but error handling addition.
So what we've done is we've taken the external libraries edition, CH10 and we've copied it over with some small changes.
Remember the way it worked before is we gave it that cool dropdown thing where it could figure out what, you know what you're starting to type like a Oh do you want to type error and it would just complete that for us.
We've fallen back in a bit in our get roll here.
Where we're going to get the input from the user and we're converting it to an integer again.
Specifically 'cause that's a super easy way for us to crash the program.
Now, notice there's some requirements that are here we got to install from our requirements file.
There's a couple of options.
We can click this button, and that's great or we can come down here.
Make sure your virtual environment is active and you can say, pip install -r requirements.txt and it'll complete that for us.
Cool, now we should be able to run this program.
We don't care about this extension for the requirements.txt.
A lot of the extensions in PyCharm are awesome.
They've got great ones for like, CSVs and Nginx files, and all kinds of stuff.
But for some reason the requirement one messes with that little dialogue that you just saw there, that yellow bar so I don't use it.
Anyway, we're ready to run our game here.
Let's see that it works.
Let's see that everything is working good.
Yes, my name is Michael, or is it Crash Bandit?
Okay, seven, yeah, not so much.
That's not great.
But one thing that's cool about PyCharm is when you do have an error notice over here on the right you can see the various places where this is happening and we can just click right here and yeah bump that down a little bit and it takes us right to the line where the error first happened.
Well, here's where the error is.
So you can see what's going on.
We're passing in seven as like this and it really wants us to pass in that the numeral 7, but it's not going to happen, is it?
So it's this error right here, and in fact we can sort of guard against this whole bit right there to make sure that everything is working correctly.
We'll see how to do that next.
|
|
show
|
6:04 |
We've identified the problem here's where our program is crashing when we type in the word seven instead of the number 7.
So what we can do is we can actually use Python's error handling exception handling behavior.
So the way that Python works, is yes we get back inputs and we can check certain things, like we can check that they, you know we could say, if text is None or not text.strip we get return, nothing or I can say Oh, that's a problem, we could print out you have to enter something, okay Print.
Alright, if we do this, it'll get us somewhere it'll get us a little farther, we come down here and my name is Michael, I want to enter that.
It says, you must enter a response.
great English.
Try again.
You must enter a response.
there we go.
Let's put in seven.
Oh, seven, nope.
Didn't work.
Did not work.
There's a small problem I think was just the stuff I copied over.
But, the problem is, yeah we're checking this here but, remember, if I type in the word seven It's going to pass this.
And then it's going to try to convert it to an integer, and it's going to crash.
So the point is, that Python, it's understanding is that it's going to raise, what is called raise an exception.
And instead of returning a value it's going to just say We're done executing, now we're in error state we're in error mode, now we're going to just work our way through the program until we find some error handling code.
So what we want to do, is we want to go in here and add some of that error handing code into this section for the moment.
So here's how it works, what you do in Python and many programming languages actually C#, C++, Java and so on, is you say we're about to enter something that might not work.
It might not work at this level or it might not work deeper down in a function that's called by a function that's called by a function down there, something might go wrong so instead of being certain its going to work what you're going to do is you're going to take an attempt at it.
You're going to try.
We create a try block when we put all the code in here that we hope is going to work, right?
All of this stuff, we're expecting to work but if somewhere along the way, in line on 39 there's an error, we can say, there's except, we're going to try this, except for there's some kind of problem, return None.
And then, let's print out, there was some weird error.
Now, lets also make this colored, so it's easy to see.
Make it red, here we go.
Notice Pycharm has given us a little bit of a warning I'll talk about that in a second but let's see where we are with this.
Alright, my name is Michael, I'm here to throw a five.
What we're going to do if I press five is we're going to come along and just go through the try spot.
We're going to make our way down and eventually we're going to either return none or we're going to return something.
We're only going to end up into this section if there's a crash okay, like we saw with that invalid literal.
So we're just say five, that should be fine make that a little bit bigger not sure why there was some kind of lag but I rolled five, Nat picked sponge computer picked sponge let's do seven then number, then numeral, seven.
That worked, I took the round, yes.
Let's keep going, seven.
That's working for me.
Nope, a tie again.
But what if I say seven.
Remember this crashed, but now what's going to happen is it's going to come down till it gets to here it's going to make it's way down to here and then it hits this, it goes oh, error.
There's an error, stop what you're doing jump immediately to the next exception handler the next except block, and deal with that.
Okay, so let's try that.
I'm going to come down here and I'm going to type seven.
Instead of the big crash we saw we get oh, there was some weird error.
Try again.
Remember, we don't now what's going on, we just said we ended up in this error case.
There could be many reasons why.
So, yeah that's not great.
Let's try hitting this button.
Oh, there was some weird error again, and now oddly it has this skull, like that really didn't work.
We tried to stop it from language actually it's raised in an error which got caught right here, you have to force kill it if you really want it to go away, okay.
So, we need to be more, gentle, more specific about this so we can come down here and say let's just for a second, just tell it to throw the error again, just so we can see it really quick.
Notice right here, this line the error is ValueError, bunch of details forget the details, what we care about is ValueError.
We go here, we can say we're going to be more specific we're going to except ValueError as a variable if we want.
We can come down here and say could not convert to integer and we could just say that we know because it's a ValueError that this happened most likely.
But we can also give them some more details and we can say V-E- here if we want and we also want to return None that's our single to the loop that hey, that get input didn't work, try again.
Michael, and let's just put junk were going to go to our error handling and it said, could not convert to integer invalid literal for int with base ten that junk I typed and it says try again.
Let me type seven No, how about seven like that, works like a champ.
So the normal path goes through the try and then just leaves, but if there's an error it jumps to this except block.
Now, we've got a much more friendly game.
Instead of just going, boom well, I guess the games over 'cause you didn't type in one to seven exactly right it just says, no, no wrong number why don't we try again?
The way that we did that, is we added a try block here and an except block that caught the error we do not have to have this as V-E if you just want to say, this could not convert to an integer you don't care about the details you don't need to say the variables but if you want the details of what went wrong then you need to say the variable.
You can also say like, this but you saw that Pycharm didn't like it and saying like, you're going to catch everything even that when I tried to exit the program it didn't work, so, it's not, not great.
So, let's try to be specific and say I'm looking through this error, here.
|
|
show
|
7:16 |
Well, that was pretty excellent.
We've got the error handling, I think pretty solid around this text input thing here.
However, remember this rules.json that we created?
How cool was it?
One of the selling points that I told you that would make this neat is it would allow for people who are not programmers to go and add in their own thing right here.
But, people being people and especially non-developers messing with code-like files things can go wrong.
So for example, what if minor mistake on line 13 no coincidence there, what an unlucky line that is.
Minor mistake.
Something is not right here.
So, what's wrong is of course we need that comma.
If you had a proper tool like PyCharm it would tell you you need a comma.
But, most people probably won't edit it with something like that who are just fooling with this thing.
So let's try to run it again.
Now is it going to work if I try to run this?
Well, that's amazing, not at all.
So it showed our little header, cool.
And, and then it didn't even start.
It didn't say something was wrong, it just, boom, exploded.
Again, you have the error.
We want to handle that error so let's grab the type of error that it is.
The type of exception.
And it says details about this and we can deal with it or not.
Incorporate that or not.
Let's go over here and say we're going to deal with it when this goes wrong.
And we're not needing that in this example.
Now, could put this just in load rolls but I kind of want, when it runs down here if something goes wrong with loading the rolls we can't play, right?
It's done.
The game is fully broken.
So what I'm going to do is I'm going to put this whole thing in here into a try.
Do an indent.
Except, and we could just put print error starting for now.
And we try to run it again.
Error starting.
It's not super helpful for us.
Let's put some color in this.
From light red.
Like that.
Well, that's better.
It's a red error starting, why?
What's wrong with it?
Well let's be a little bit more specific.
Let's fit it in here we're going to have an except a block.
You can have more than one of these we're going to have that json.decoder.json error and we can just start for now like that, hit Print.
Error the format and the file rolls.json is invalid JSON.
How 'about that.
Now if we try to run it, it's going to come down and it's going to start looking through all the things listed here and saying which one matches the error that is a JSON error?
Well, this one.
And we try to run it, error the file rolls.json is invalid JSON.
Cool, well, it'd be cool to give them a little more detail here.
So we could come over here and actually put the message.
We make that an F string and we declare a variable as je for JSON error.
We could print that out and let's try it again.
Here we go, error, the file rolls.json is invalid.
We're expecting a comma on line 14.
That's cool because that means that people who are messing with it it now tells them not just, oh, it's broken no no no, go to line 14 and we're expecting something, right here.
Well, what's right before that that's missing?
There we go, now if we run it, ah, it's working again.
Super cool, right?
So we're able to deal with that.
Let's actually look at one more thing.
Let me run it again.
I want to run it outside of PyCharm.
There like that, and I want it to wrap around just so you can see.
Easier to copy this way.
So let's go run that out here, like this.
We could just type this again, My name is Michael and if I hit that, error starting.
Hm, that's weird.
So let's go back and actually maybe even take that error away over here.
Let's see.
This error starting bit.
So now, if we run it again, My name is Michael and I try to exit out, I get this oh, it's all broken.
Keyboard interrupt.
Again, that's the error type.
So let's go and actually go here and say we're going to catch keyboard interrupt as well.
We don't need to create a variable that holds this.
There's nothing really to do.
And it's not even an error.
We'll just do, right, they just are trying to exit but that's the way Python does it.
We'll go with a light cyan, you got to run, okay see you next time.
All right, let's try this again see if we can do better than this look here.
Again, My name is Michael, oh actually, I want out Ctrl+C, you got to run?
Okay, see you next time.
Because we are on an input line, yeah the print put it here so I kind of would like to do a print before all of these.
Let's just do prints here and go on.
Oh, one more.
One more test.
We'll see, got to run?
Okay, see you next time.
No problem.
And color's even back.
Yeah, this is great.
So we're actually handling these errors at the different levels, right?
So over here we call into rolls, go down rolls calls open, that worked, and it calls load but load looks at the file and says Oh no, something is really wrong here.
One more thing we might want to check for if we're letting people mess with the rolls is file not found error.
And we could just say error, rolls file, rolls file.
And then here, let's put FE for that.
So, this might occur, this file not found might occur if we, let's go in the right directory we're over here, and we renamed rolls.
Now it's gone, and we try to play our game.
Rolls file not found no such file or directory and it tells them, Here's a huge great long file that we were looking for that's not there.
So let's put it back.
Now we should be able to play again.
But we gave 'em a nice message instead of again it just crashing wide open, right?
Now, My name is Michael, let's try around here.
Let's go for seven, yeah, no, you can't do that.
Let's go for seven, throw some water just going to start throwing water on this thing.
Oh yeah, tied, here it takes the round.
Again.
How many times has this thing beat me?
Well I guess we didn't copy over the leader board.
But it's beaten me a lot.
Ctrl+C.
I'm out of here, I don't want to play anymore.
You got to run?
Okay, see you next time.
So hopefully that gives you a sense of how working with error handling in Python using try and except blocks, where we try to do something and we have except blocks for the specific errors that we're trying to deal with.
One more thing we can have down here we can have except exception, like that.
And then down here we can just print as X something like that.
And we can put escape with errors just error with the game or something like that.
Unknown error.
X in there and make it an F string, there we go.
All right, looks like that's good.
So that'll catch some unknown error that we might not have expected and at least it'll print out a message instead of flat-out crashing.
Now here we have it.
This is a lot of stuff but it's just in our main file.
It's kind of like is the final catch-all.
We also had some in our play game where we were actually getting the input at a lower level.
So you can have it at different levels of your program.
|
|
show
|
3:08 |
I want to do one more thing to just make sure that you're really getting in the feel for how the control flow works when we hit these errors.
I'm going to set a breakpoint, right up here.
And I'm going to hit the debug button.
And I'm going to come in here, and we're going to step either over or into our code.
So let's step over this, over this, we don't care about the log stuff, we don't care about the header stuff.
And let's go into this load_rolls here, and first I'm going to really quickly break this.
Let's see what's going to happen.
Let's hit this first, step into our code.
And this is fine, this is fine, this is fine.
We've opened it you can see, opened up to that file.
A little more info.
But this, if we even step into this, and go deep down into, into Python itself and as we try to work through these steps what's going to happen, this is going to hit this line and go broken!
And now it stops, what is this?
No, nothing.
Keep going.
And it's going to start going down through here.
And now this one is going to actually match this and go in here so, it's not going to be so unexpected.
But it says we have this error, which we named je no not surprising and off it goes.
And then it just exits and so it picked one of those blocks and it went.
Put this back.
And let's debug it again.
This time, let's go through, over step over.
I'm not going to go until we start playing the game a little.
We'll go down and do that.
It wants my name I guess.
And I'm going to go in, and-whoops console.
I want to throw seven, now actually I wanted to stop down here.
So I didn't step and do it correctly so I have to set the breakpoint down here.
Which is fine, and get roll, and now my roll is now let's say seven correctly.
So, I'm going to step over, and it's going to print out the rolls.
Let's not do the breakpoint there, and right down to here.
It asks what our roll is, and it's going to be seven.
And now we're back here, and it got the word seven numeral.
It's gong to convert that successfully I'm going to say it's fine and just going to return it's not going to go into the errors but it's good, comes down and it just keeps playing.
And off it goes.
I don't know if I won, but I'm going to find out let's go down a little bit farther to see if I won.
I, think I won?
Yes I took the round.
Alright let's go farther.
And now let me type in some junk, something broken.
So, broken.
This is broken.
It's fine.
It says it's not nothing, so everything's good.
But we're going to try this, and it's going to first say, I'm going to start going up till I find the first except, the first try-except block.
It just happens to be right here it could be that main one as well.
So we're going to come over here and step.
Not going to work, so it goes straight here.
Handles the error, returns it up here and it doesn't go all the way the main but it says alright we dealt with it and what we decided to do is return none for roll one when something invalid was done.
So that way, we can trigger this bit of code to just make us do it again.
So as you're exploring this error handling be sure to use the debugger and step over and into and out of your code to explore the flow of the errors as you go through the program.
|
|
show
|
1:26 |
Let's quickly review catching, prying to run code and then catching errors that may result from running that code using try except blocks.
So, here's some code that handles two specific errors through a whole bunch of our program.
We run basically the entire program and if ever we get a keyboard interrupt that's control C.
It says let's print out hey, you're out of here it looks like you got a run.
No problem, goodbye.
And if the rolls dot JSON file is malformed we want to catch that error and say there's a problem with the rolls dot JSON file here are the details.
The way we do that is we say try: and into that try block, we get into the block bind ending.
We have all the stuff that we think might cause a problem and then we except.
Here's one error type, except.
Here's another error type and Python will automatically say if we encounter an exception we're going to go and look at the various error types and see which one matches.
It's important to know that it's going to go down that list and the first one that matches it's going to go with that.
So if you have a very general thing like except exception and then except JSON decode error which is also an exception it's like squares and rectangle sort of thing.
It's going to stop on the first, more generic one.
So you got to put the most specific stuff first and the most general stuff last.
That's why I had that except exception as x at the very end of my example before.
You can declare a variable, JE and use it to get more details or, if you don't care about that you don't want to do anything with the details just catch the exception type itself.
|
|
show
|
1:25 |
Of course it's time for you to practice adding air handling, creating exceptions and catching them in your program.
So that's what we're going to do in this practice exercise.
Here we are over in CH11, Error Handling and we have a couple core concepts.
The basic try/except, which we talk about details here and then also the more advanced what do you do if you want to catch multiple errors in one try block?
Like the JSON itself is malformed or the file isn't there or the conversion didn't work or who knows what.
So it talks a little about that and then for your exercises go back to tic tac toe that we created or if you made it as far as Connect 4 in our practice exercise, you want to use this one and the idea is to add error handling around first the user input into the program using try and except, and then think of other ways that your program could crash like for example Control C from the terminal that doesn't work in PyCharm but it does if you run it from the terminal or maybe files are missing or other types of things that could go wrong, so you can check the trace back, that's the big dump of what went wrong for the error type and you can add appropriate error handling for those as well.
So just practice making your program much more polished taking that input and handling those errors gracefully.
This is the sign of a professional, properly written program not one that just takes only the happy path and then anything at all deviates it crashes, you don't want an app like that.
So take this time to make your apps more solid.
|
|
|
13:23 |
|
show
|
0:29 |
There it is, you've made it.
After all this work and studying and practice you've crossed the finish line.
You now possess the superpowers of one of the world's most popular programing languages.
In this final chapter of the course we're going to take just one minute per topic per chapter and summarize what you've learned to help it stick for the very last time here.
I hope you had a great time in this course and I hope you're empowered to go and build amazing things.
|
|
show
|
2:00 |
One of the first ideas that we explored were variables and assigning values to them.
For example, we open the Python REPL and we said x = 42.
In this language, in Python you have very little ceremony that you have to go through to declare variables and set them up and give them values.
We don't have to say, we're creating an integer called x or a string called name or anything like that.
No, we just say the variable name equals the value.
But remember, you do have to keep in mind that there is an underlying set of different types of variables and data, and they can only interact usually, when they're the same type.
For example, we could take a list and combine it with another list we could take numbers and do math with them we could take strings and combine them to make larger strings but you can't take a number and a string and combine it using the standard operators or anything like that and have that work out but here we said x = 42 and y = 19.
These are both integers and then we did some math with them and what we got back is another integer, 175.
We also wanted to create some text type data.
In programming, we now know this is called a string.
So we're going to say name equals Michael and if you were to ask what is the type of name it would say it's a string, of course.
If you try to combine them like I indicated before you're going to get some kind of error.
In this case, type error can only concatenate strings, not integers.
Though we saw we also have to use f-strings or formatted strings.
Generally we want to take different types of data and combine them into some kind of final text output high, curly, name, and that variable name gets plopped in there by Python.
Looks like you just did math, and it has the value of x the value of y, and then you can even put the expression.
Remember, it maybe makes more sense to assign like a z variable for the x + 7 * y but just to show you can have actual computation and expressions and evaluations in there we put that statement in there again and we get this, Hey, Michael, looks like you did math.
42 + 7 * 19 = 175.
|
|
show
|
1:01 |
One of the first interesting parts of programming that we focused on was conditional statements.
Remember we were talking about how to make code, decide and make it interactive?
So, here we're getting a random number from the computer.
Remember that was the number of M&Ms in the jar and then we're getting a guess from the user on whether or not, you know, whatever number of M&Ms they thought there were there.
And then we can check.
If the guess is too low, we can say Your guess is too low.
If it's too high, we say, it's too high and if they win, then they win.
And this let us go around and around until they got the number of guesses right or they ran out of attempts.
Remember they got five attempts to get it right they got a free lunch, or they just didn't get anything and had to pay for lunch.
So, these conditional statements either are if elif, there's all these combinations you can have but they always start with if and they have some kind of truthy test like guess less the number or if you have a string you just put the string there and say if there is a value for the string we're going to do this thing and so on.
So, if, elif, else and you put the -uthy type of statements in there to check them.
|
|
show
|
1:43 |
One of the most powerful tools we have in our programming toolbox for changing the way that we think about and work with our code is functions.
Functions allow us to group together a bunch of small little steps into one very simple step.
Here we have a bunch of things going on we have a function called play around.
It takes some arguments and then we take a bunch of work inside the function.
But all that matters once we write this when we want to use it we know pass player_1 and player_2's name and then what we'll get back is the value of the winner.
Either player_1 or player_2 or if there's a tie, we get none.
And that allows us two really important things.
One, it allows up to think about well this step is where you play the round.
We don't have to worry about the details.
Remember in our later part of the course we changed the way that we got the input from the users.
We got that instead of just saying input and type in a number we actually used that autocomplete thing.
The stuff that was calling get play or get role from the user they didn't have to go and know that we changed how that worked.
It just got changed and everywhere we used it automatically the better version got used.
It allows us to hide away and not worry about the details just used the high level idea of playing around.
It also lets us organize our code in a way that is much simpler.
We can think about here we're going to play around we're going to check for the winner.
If there's enough winners.
I have enough wins for any given player we're going to exit out of the loop and they win.
It allows you to think at a very high level instead of at every single bit you're thinking about the details.
Super cool.
Be sure to make use of functions try to keep them short and small.
If they get really long and cumbersome you probably want to break that further into smaller functions.
Allow you to get smaller and smaller detail as you go down and not get things too complicated all in one place.
|
|
show
|
2:19 |
The next things that we talked about were data structures.
And we had started with code that looked like this, on the left.
And remember, our dog, was not impressed.
Not even a little bit.
Because that is some bad code that is hard to maintain hard to evolve and much, much more.
We went into all the details there.
We saw though, that important data structures that are built into Python lists and dictionaries in particular allow us to build much cleaner code.
And what's really pretty amazing is we made our game way more complicated by just changing the definition of that dictionary or even the JSON file that was loaded into a dictionary without even touching the code that operated a game.
I mean that's really, really impressive.
So, couple things we can do with dictionaries.
We can create them.
We can create them with their name their class name, like this.
Or we can create them with these curly braces, like so.
We can even create them pre-populated like here we're creating a dictionary that has 2 wins for Bill, 7 for Zoe, and 4 for Michael.
That's equivalent to creating it like this as well where you say, as a string key: value.
key: value.
So on.
If we want to get a value back out, like how many times has Zoe won?
We're going to have a key.
And usually this is not hard coded like, quote Zoe.
It's some variable that you've gotten its value assigned to.
And then we can say well whoever's value is in name they have however many wins we'd get out.
Now remember, we must have that value as a key or it's going to crash.
But for Zoe we have her, so it's says wins by Zoe are seven.
If we don't have Zoe in the dictionary this is going to throw a key error and crash and we'll be out of luck.
Our program's going to stop.
Not going to be impressive.
So what we can do is we can attempt to get the value out of the dictionary with a .Get instead of the square brackets and pass the key.
What we get back is either a value for the wins or none in this case if there's no value for that name.
In this case, we're actually leveraging the truthiness of wins.
If it comes back as None, going to be False.
If it comes back as 0, also no wins.
Going to be false, we'll say no games played.
Otherwise, it's going to come back and say there's one, two, three, five wins, so on.
Dictionaries also list those are the two most important data structures that we worked with throughout this course.
|
|
show
|
2:05 |
Next thing we discussed were some techniques for problem solving.
Remember it's very challenging when you sit down at just a blank screen to start writing code.
Because it's there's so many ways you can go.
So many ways you can solve it.
And if you don't break it down in the right way it's actually kind of challenging.
We talked about these different ways and these techniques that you can use.
One was, have I seen a similar problem solved before?
And which way is this similar?
And can I use the same solution for that part of it?
Visualizing the data helps you understand what you're working with.
Leads ahead to thinking about what data structures or how you're going to store and pass it around.
Divide and conquer is a huge part of this.
We did this with all our games, and our algorithms.
We sketched out like these are the four or five things we got to do to make this work.
And then you don't have one big problem you have five small problems.
And that's much easier to solve.
Run through the data structures.
We saw that switching from some giant if else if else nested if else statement to just a dictionary turned out to be super powerful.
And even made our code more flexible.
It was more readable, more maintainable and it had other benefits that we maybe didn't see coming.
Is there an existing pypi package.
Meaning, you were thinking about solving some problem.
Instead of writing all the code to do it is there something basically out there?
There 215,000 packages over at pypi.org.
Chances are, a lot of the challenges you're facing can be a couple of function calls against those libraries that you don't have to work on.
That's the best way to do it if you can.
Remember, struggling with working through these problems that's part of the journey.
That's also part of the payoff.
So when you get it right and when you finish that program and you get it working the joy is overcoming all these steps.
So this is just part of the journey and embrace it.
And don't suffer from analysis paralysis, just start.
We have cool refactoring tools built into our software.
The software's easy to change and you honestly won't know all the details that you need to think about until you're part way through solving the problem.
A lot of times the best thing to do is quickly run through the stuff and just get started and change it as you learn more.
|
|
show
|
1:30 |
Once we rewrote our Rock Paper Scissor game with data structures it turns out it's pretty easy to save and load those data structures from files.
The next topic we covered was File IO and File IO usually starts around the open function.
The open function creates this file string either an input or output string and you need to make sure it gets flushed and closed properly so you want to put it into a width block.
That's what we're doing at the bottom of this screen here.
With open, give it a file, this one's for reading so we say R, specify the encoding just to be explicit there and we give it a variable name, Fin.
I like fin for file input string so the name tells you, you can't write to it and here we're actually going to load up a JSON file so we don't need to understand how JSON works.
All we need to do is input the JSON library and say, hey, here's a file string to something you understand.
Go get us the data, put it into rows.
That will be a dictionary on the Python side of things.
We also saw that working with paths is tricky and knowing where you're actually located can be a challenge.
Remember, this is based on the working directory.
And trying to put these together and work with them is also tricky in a cross-platform way.
Windows and POSIX macOS, Linux systems have different separators and definitions of how you put files together.
That's why we use the OS.path module because it knows how to do this for us regardless of the operating system we're on.
This is just one of the things we did with files throughout the course and I think you'll agree they added a lot to our little program.
|
|
show
|
0:57 |
While Python is a very powerful language on its own with its standard library, things like json and os and whatnot that we can work with it's the libraries, the external packages that make it truly magical.
Remember you can even type import anti-gravity into the Python repo and it'll launch up this page in your web browser.
No, if you have a problem to solve be sure to go look for external libraries that you can use.
And remember a good place to start was awesomePython.com because those are some of the better categorized ones you might choose, it's not the only place to be sure but it is a good place.
And you can always go to pypi.org and do a search and look around there.
However you come across them we install our libraries with pip and then we create a virtual environment activate that virtual environment then we say pip install the name of the package and then you can just import that package and start running with it.
Hopefully working with external packages makes you love Python as much as that guy who was up there flying around.
|
|
show
|
0:24 |
You're probably very familiar with the GitHub repository for this course at this point.
Remember all the practices exercises that you've had to go and get there?
I just want to remind you, in case, for some reason you haven't stared and downloaded and download or clone to this or even forked it to your own GitHub account go ahead and do that now so that you make sure that you have this with you as long as you need it after you're done with this course.
|
|
show
|
0:55 |
Finally, I want to say thank you.
Thank you for taking my course.
I'm really glad you made it this far to the end.
I hope you had a great time learning Python.
Connect with me on Twitter.
Over there, I'm @MKennedy and I will see you online or in another course.
Now, it is time for you to get out there and get in the game.
You've done all this practice you've done all this studying.
Now, it's time to go out there and start building amazing things.
You start building stuff just to help around your day-to-day life.
At your job or in your studies or in your research you can create simple little Python programs that take the tedious stuff and make it automated and more powerful and more reliable.
And, of course, you can go out there and start learning web frameworks database technologies, data science and start building real things for other people to start using and make their lives better.
But, just like with problem solving, you just have to start.
Get out there and get in the game.
|
|
|
3:37 |
|
show
|
1:54 |
In this brief appendix I want to show you how you can set up Jupyter as your editor for this course.
Well, first of all, what is Jupyter?
Jupyter, and Jupyter Notebooks, are these live half-descriptive in presentation and half-coding interactive webpages I guess, for the lack of a better word.
Here's an example where someone's exploring the algorithms, or the Lorenz differential equations.
See, they're writing a little bit of description and then they're loading up some Python and they have some more description then they're running some Python.
And you get a picture, and so on.
Now, before we get into showing you how this works and why you might use it I want to point out that during the course we are using PyCharm Community Edition.
That's free.
Jupyter's also free.
That's free and open source.
And that's what I'm going to be doing.
I think that is the best way for beginners to get started and honestly one of best ways for professional developers to work as well.
That's how I work, every day.
The reason I'm saying that is if you can use the PyCharm Community Edition please do that.
It'll be the closest match to what we have happening in the course.
Well, why might you want to use Jupyter after that statement, right?
Jupyter Notebooks are very very popular in data science and if you're going down the data science side of things you might want to work in this tool.
You might want to just get some exposure to it and you know, it doesn't have to be all or nothing you can do some work in Jupyter you can do some work in PyCharm.
Now, I do want to point out in Jupyter, the last, not the last two of the chapters, the second to last two chapters will not work in Jupyter at least not correctly.
Not the way we expect them to work so the one working on external libraries I don't think that's going to work and possibly the air handling one as it's done currently.
So there's definitely a reason to use other editors but if you are on that data science side of things and you just want to get some experience being in a notebook by all means, set it up and use it for your editor as part of this course it'll get you great exposure.
|
|
show
|
1:43 |
Let's talk real quickly about installing Jupyter Notebooks.
If you install Jupyter Notebooks you're going to have to have Python already Python 3, already set up and installed.
And then, you're going to run this command in either the command prompt or in the terminal.
You're going to run pip3 install --user --upgrade jupyterlab.
On Windows, you might have to emit the 3 depending on how you've installed it.
But I think pip3 will work on both operating systems in the latest version.
So this is going to download Jupyter Lab and all of its dependencies.
This, we talk more about pip later in the course but if you want to set this up this is how you do it.
So you got to run this command, we'll expand on it later.
Once you've done that you should be able to launch Jupyter Lab and the way you do that is you type jupyter lab like so.
And here you can see what it's going to do is it's going to start up a little web server and it's going to go to this url says down here access your notebook open this in the browser.
But what's actually going to happen is it's going to pop open automatically like this.
So you won't even typically have to at least the first time, launch it.
It'll automatically launch itself.
So here you'll be logged in.
And to get started, you just click on a new notebook.
Make sure you click on Python 3.
And also when you type this command about jupyter lab do that in the folder that you would like to see on the left here.
The working directory.
'Cause when you say new Jupyter Notebook it's going to create it in whatever folder Jupyter Lab was started from.
Okay.
Once you do this, you'll have Jupyter Lab up and running.
There's a file menu, or a menu at the top that shows you how to do the things and learn the hotkeys and get going.
Again, if you can use PyCharm Community do that because it'll be a good match.
But if you want to get some exposure with Jupyter and Jupyter Lab, that's good especially if you're in the data science side of things.
So you can use this some of the time as well.
|