[MUSIC] So in this video, we'd like to think back about all of the peer interviewing that you've done up until now. And really get ready for the peer review for this week where you'll be looking at each other's project reports. Both the design documents and the codes themselves. Now you've done a lot of peer review in this specialization, and you've probably come up with some great mechanisms to do so. And what we want to do is just highlight some best practices, especially when you're reviewing code. And think about some of the pitfalls, potential pitfalls and how to avoid them when we're doing peer and code review. So, first of all, why peer review? You're all becoming experts at doing so because you see it throughout all of Coursera. It's the Coursera way, but there's really a reason for that. And one reason for doing so much peer review is how much we can learn from one another. And how we can learn from seeing other people's solutions to similar problems as our own. Now in this course, there's an even greater emphasis on peer review. And that's because since the projects are so open-ended. Peer review is really the only way we can give you feedback on what you've done. We can't do autograding as much, other than in the warm up questions. And we can't really guide you through very specific design documents. Because that would go against the whole purpose of a capstone project. Where you're really showcasing your creativity and your design and vision. So peer review is at the heart of learning from one another and giving feedback, and so how do we do it effectively? And as you've probably noticed, peer review takes a lot of focus, attention and effort. And so it's important to give that effort and attention, but not try to drag yourself out and do it too long at a time. And so if you're feeling yourself getting a little bit fatigued, it's really important to step away from the peer review. There's been a lot of research on to the cognitive load that it takes to do these reviews and to give feedback to one another. And the quality of the feedback we give one another really declines if we try to push through and do too many at once. So make sure you're looking at each other's work with fresh eyes. And as you're looking at the work with fresh eyes. Make sure that you're looking at the documentation of the code for multiple perspectives. So you'll find that it's useful to look at the project as a whole, analyze the design document that you're being presented with. Understand the questions that are being asked and the big picture algorithms that are being used. But also then dig down and look at the small details about how those algorithms are being implemented in the code. So let's think about the aspects of the coding that you'll be doing, of the code reviewing that you'll be doing. And as you're reviewing, remember that the point is the communication. So remember that as you're communicating with one another, you want to give specific, actionable, constructive feedback. Think about when you receive feedback about your work. The most productive feedback I receive always highlights what's good about the work that I've done, but also how I can improve it. And it gives me really concrete next steps for my improvement of the material that I'm producing of the task that I'm working on. And so we want to make sure that there is no gap between the advice that we are giving our recipients of the peer review and what they're hearing. And make sure that we are staying very positive and productive. So as you're reviewing, you will definitely want to think about the design of the project. And what, as a first step, many of us do when we're going to implement a big project like this. Is we have to design the class hierarchy and the inheritance structure of those classes. And so, your feedback on that design will be really useful because there's so many choices to be made there. Think back all the way to course one, where we thought about these UML diagrams. And how they can act as road maps when we analyze code, and when we try to read someone else's code. And so as you're noting down the UML diagrams of the code that you're reading for your peer review. You can see if those choices that the person has made really reflect sound design practices. Whether the interfaces are clean, whether private data is exposed, whether there's the appropriate number of classes. And whether those classes group meaningful data and methods together into objects. And so once you've thought about the way that the code is being organized. You can also think about the design of the algorithm and the data structures that are being used within these classes. And think about how they address, in that big picture holistic perspective, the questions that are being asked. And then, at that point, we're really ready to look at the code in some detail. And we want to think about the code that's being presented to us and make sure that there isn't redundant code. We've got all these wonderful features in our programming languages that let us eliminate code by packaging it up into methods. And so, we don't need to repeat ourselves, and so, did the person make use of those great features? Did they use meaningful variable names, so that it's easy to read and understand what these variables are doing? And are the lines of code indented and spaced in a way that facilitates easy reading? Part of being able to read the code well is also having the methods well organized, both in a logical order within the class. But also so that they're short, and so that we can understand, as a whole, what the function of each method is. So, that's all very abstract, but let's look at an actual piece of code. And, I have to preface this by saying, that this code, it's in pretty good shape, so if you see this as a part of your peer review. We definitely want to give some great positive feedback to the code that we're seeing over here. And remember throughout that critique does not just mean criticism. When we are reviewing and critiquing one another's' work, we want to highlight the pros, as well as the places that can be improved. So what we can say is excellent about this code is the way that it's laid out, it's very nicely indented and spaced. Also, we can look at the methods and the way that we're using helper methods as part of implementing that big top-level method. Really breaks down the functionality of the methods so each piece is a manageable chunk that we can express and implement. And so, these are really nice, short, well structured methods. One thing we might point out, though, is that in that middle piece over here, where we're declaring a couple of new variables. Those variable names maybe could be a little bit more helpful. Maybe they could be a little bit more descriptive instead of just saying m0 and e0, maybe we could say max and edge max. And that's really going back to what the comment is telling us that these variables are going to do. But we could also observe that that comment is really useful. And so we could express that the commenting that's being done in this piece of code is really very effective. Now we could continue to trace through this code and notice that we've got a nested for leap. Where we're really iterating through vertices in order to iterate through the edges that are incidents on those vertices. And so what we're seeing in this method is that we want to compute the Edge with heist between this. And so we're going through all of the edges in the graph, and we're comparing there between this to our current maximum. And so what we could observe here is that the core functionality that we want is some iteration over all the edges. And the way that it's being implemented right now, we're iterating over all edges by doing this two-level iteration. And so this highlights a design decision that the person who wrote this made when he or she designed the class structure. To say that the edges really are stored as adjacency lists in the vertices. And we could raise the question to the person who we're reviewing to say, did you consider perhaps designing your graph in a different way? Where the graph itself is represented as a list of edges, and then perhaps from the edges, we could deduce their end points. And so we could put the edges front and center, and that could be a question that we raise in the peer review. So this has all been about the readability of the code. And as you're reading the code, notice that we were able to sort of understand the functionality that it was trying to implement. And so if you notice any bugs that stand out, if you notice any edge cases. Or perhaps some null point of exceptions that the code might write into, it might be useful to raise that in the peer review. Now the peer review is not really intended to be a full on testing suite of the code. You're not really intended to spend a lot of time trying to trace through line by line what the algorithm is going to do. But you can give some advice or observations if you notice something glaring. And in particular, if you have ideas about how you would test code. You can make those comments when you're reviewing the design document. Because a design document does include the testing strategy that the person who's programming this project is using and has been using throughout. And so you can comment on the project at all of these different levels. So to wrap up, this peer review process really exercises all of your software engineering muscles. And I do hope that you get a great experience, both from reading each other's code. And also from just seeing all of the amazing projects that your classmates have done throughout this capstone project.