How to handle a colleague who hasn't pulled their weight
When students come to me with problems like these, I very rarely just take the side of the active student against the "lazy" one. 

If you work in a group, you're both responsible when the dynamic doesn't work. And keeping the group dynamic healthy is something every student should learn. I know how difficult it is, I've been both the lazy student and the active one.

It may feel to you like there's nothing you possibly could've done. But that's never true. You started the project by immediately splitting the work load, and reducing the level of necessary communication to a bare minimum. He took the easy half, because he was busy. When his work started to lag behind, you began to write specifications for him.

All this combined probably sapped his motivation. Every step along the way took the challenge out of his part, while he still had those thousands of lines of code to get through. Meanwhile you felt like you were doing more than your share, but you were getting things done, and things that you designed, problems you solved.

In a healthy project, you communicate and you meet often. You don't divide the workload to minimize communication, you use your shared expertise and you design together. That way, you both stay motivated, because you both feel like it's still your project.

What you're doing now is focusing on everything that he could be doing differently. That may be the fair option (cause you're doing all the work), but it's not a productive option, cause that's not a dimension you control. You should be asking yourself what you could've done differently. It may feel unfair, but it's something you can actually implement, so you'll feel a lot less powerless.

Anyway, that's a lesson for the next project. For this one, I'd say remain detached. It's not your responsibility to make sure John learns something, and you'll get the same grade either way. Talk to him, tell him you're unhappy with the way the project's gone and ask if you could've done anything differently to get him more motivated. Let him know you don't expect to be working with him on future project and you're better off as friends than as collaborators. 

Just make sure you don't get angry with him. Anger might've been productive halfway down the project, but you're too late now.