Don't be so hard on yourself. Go ahead and get it wrong the first time. Make it work, make it right, make it fast.
Getting it wrong the first time is a great way to avoid getting stuck. You just type the first thing that comes to mind. The important thing is that you're typing.
What these students don't realize, and what I have learned in my years of building web apps, is that you have to do things the wrong way before you can do them the right way.
What designers need more than anything is an environment where it’s safe to try things out. This happens when everyone accepts that things often need to be wrong before they can be right. Failure (and I use this term in the broad sense) is a necessary and valuable stage in the journey to a solution.
The first couple of times you do it, you're not going to be very good at it. Hey, you might not be very good at it for months, but if you make it a habit to try it, slowly, eventually, you'll actually be good at it. You'll even start to like it.
Most people don't give themselves permission to suck.
I'm willing to copy-and-paste to get a test passing, but once the test passes, I can usually remove the duplication quickly. I'm willing to extract code into a method and call it foo() in order to get rid of duplicate code, although that name foo() rarely survives more than 15 minutes. Finally, I will gladly introduce interfaces, classes, methods and variables to clarify the intent of a piece of code, although generally speaking once I make things more clear, I can find things to cut.
Don't be afraid to be wrong. When you don't know what the right design choice is, make a decision and stay principled. If you are making a non ideal design choice but the code is clean, refactoring to the right choice down the road should be trivial. The beauty of software is that nothing is permanent. So we should act like it when deciding what design choices to follow.
We cannot emphasize strongly enough that "first-cut" code is not finished. It's good enough to sort out our ideas and make sure we have everything in place, but it's unlikely to express its intentions cleanly.
This implementation may seem gratuitously naive—after all, we should be able to design a structure as simple as this, but we've often found it worth writing a small amount of ugly code and seeing how it falls out. It helps us test our ideas before we've gone too far, and sometimes the results can be surprising. The important point is to make sure we don't leave it ugly.
There's a simple reason why tackling a hard problem can lead to depressive symptoms: you're necessarily wrong 99% of the time.
So many times in my work I've fantasized about the solution to an idea, and have been too afraid to implement it because of the subliminal fear that I will be, yet again, wrong.
The point is to be aware. If you find yourself resisting an obvious step due to an irrational fear, step back and force yourself to push onward. You only need to be right 1% of the time.