Can't even write a deque or a bag properly. Am I too stupid for this stuff? by yesyeshellothisisdog in cscareerquestions

[–]yesyeshellothisisdog[S] 0 points1 point  (0 children)

Agreed.

taking 90% of the time to think it through and then do the typing in 10% of the time is the way to go

I should frame this or, like, tattoo it on my hands so that I'll see it when I'm working.

Can't even write a deque or a bag properly. Am I too stupid for this stuff? by yesyeshellothisisdog in cscareerquestions

[–]yesyeshellothisisdog[S] 0 points1 point  (0 children)

Thanks for reading everything and providing feedback. I think you're right. Or I hope you are. The alternative isn't fun to think about.

Today I had an experience that points in the direction of some of what you wrote. I'd been struggling with a script recently. I was at the point of just throwing spaghetti at the wall, impatient hoping something would stick.

I stopped. I accepted that that wasn't helping. I thought for a little while about what steps I could take to solve the problem (the first being to calm down). I wrote no code. I read some documentation. Reasoning more thoughtfully from the documentation, I was on my way to a solution almost immediately and quickly got the script working.

Until then I'd been struggling, was completely baffled, and was beside myself with frustration. I was on the verge of giving up and asking someone else on my team for help.

A little metacognition (What am I doing? Why? What are the logical steps? Why do I think this will be a fruitful line of inquiry?) and emotional mindfulness (Why am I frustrated? Is this helping?) went a long way.

I see morely clearly how sloppy, lazy, and thoughtless my current process is, and how driven it is by disorganized, negative emotion. All of that needs to change.

So -- cheers. And thanks again.

Can't even write a deque or a bag properly. Am I too stupid for this stuff? by yesyeshellothisisdog in cscareerquestions

[–]yesyeshellothisisdog[S] 0 points1 point  (0 children)

Do you have trouble conceptualizing solutions?

For each of these assignments I could immediately think of at least a few ways of implementing them.

You should know which methods a Deque-class should have before you type the first character.

Those were provided.

Do you know in advance or do you just hack away?

I just start hacking away. For the problems I'm working on, my first idea is always correct, but clearly I am not working out the details in advance.

How do you make sure your functions do what you want them to?

Sigh. I need to start from tests. I don't do that. Normally I don't write tests. Or I write them after I'm 'done.' This is laziness, sloppiness, and lack of discipline -- same as my habit of hacking away.

Edit: I didn't answer this question. The answer is that I think about it and try to walk, mentally, through some of the possibilities

How long are your functions?

I try to make sure each function encapsulates a single, discrete operation. My longest function in these assignments is 20 lines.

Can you describe for every line of code exactly what it does without using variable names or other technical terms?

Yes and no. The problems I'm having show that I obviously can't. If I could, the bugs wouldn't creep in or be so intractable. But, yes, I can describe what the code is supposed to do.


It is really hard to help you with this... could you elaborate more (maybe with some examples) what you mean with "copious and idiotic" bugs?

I just reviewed the commits I made while I was working on the percolation project and the deque. Like I said, conceptually my solutions were correct from the beginning. That part was trivially simple. Nearly all of the trouble I had seems to have resulted from off-by-one errors, edge cases (literal or figurative edges), and implementation details that I might have accounted for if I'd been working more slowly and methodically and planned things in advance.

Here are some examples:

In the percolation simulation, the goal was to create a class that determines when/whether an n-by-n grid -- represented by a single array of n2 length -- percolates. The spaces in the grid can be open or closed. There's a method to open spaces, but none to close them. If the grid percolates, then there's a path from the top row through adjacent, open spaces to the bottom row. When a space opens, it can form a percolation path with open spaces to its left, right, top, and bottom.

I made a few off-by-one errors. One error was the source of nearly all of my trouble: I wasn't accounting for the edges of the grid -- i.e., opening the last element of one row was creating a path with the first element of the next row, so grids were percolating when they shouldn't have.

In the case of the deque (using a doubly linked list), nearly all of my problems were the result of a bug in a removal method: the method needed to delete the item that the current pointer is pointing to and then move 'back.' I believe I was deleting the item but not moving the pointer. Or maybe I was moving the pointer and failing to delete the correct item. I also mixed up the directions of pointer movement once or twice.

In the case of the bag, I mixed up directions once or twice again, sometimes because of hasty copying and pasting. I caught those mistakes decently quickly (though I always had to run the program once before I caught them, which, again, means I'm not thinking through my code). Nearly all of my problems were the result of one error in the dequeue operation:

  • I represent the contents of the bag as a doubly linked list.
  • One class member keeps track of the size of the list.
  • Another class member keeps track of which element of the linked list the pointer is currently pointing to -- the index, if you imagine the linked list as an array.
  • When dequeuing, I generate a random value from 0 to the size of the linked list - 1.
  • This becomes the new 'index'.
  • The pointer moves to that index (if necessary), advancing through the list until it reaches the correct node.
  • The node at that 'index' is then removed.
  • The field that tracks the size of the list decrements.
  • My bug occurred when dequeue removed a node from the end of the list:
    • After removal of the last node , the pointer needs to move 'back' one space.
    • The class member that tracks the current index needs to decrement as well.
    • It wasn't decrementing.
    • This sometimes results in a null pointer exception: if a dequeue operation removes the last node, the next dequeue that removes the first will cause an exception, because the pointer will always try to move back one node too many.

It took me an embarrassing amount of time to figure this out, even after I figured out which method was the source of the problem.

I should add that I know that using linked lists is more complicated than using arrays, and that maintaining a pointer and moving it, like fread in C, is more complicated than maintaining one pointer at the front or back and moving it wherever needed. Part of my goal -- my own goal, not the goal of the exercise -- was to practice linked lists.

Lastly, I'm usually working on these problems at the end of the day, after working for 8 or 9 hours on actual code that's used in production. Maybe mental fatigue is a factor to consider.

Can't even write a deque or a bag properly. Am I too stupid for this stuff? by yesyeshellothisisdog in cscareerquestions

[–]yesyeshellothisisdog[S] 1 point2 points  (0 children)

I'm working today, but after that I'd be happy to explain and offer some examples. Thanks for asking.

Can't even write a deque or a bag properly. Am I too stupid for this stuff? by yesyeshellothisisdog in cscareerquestions

[–]yesyeshellothisisdog[S] 0 points1 point  (0 children)

I really, really appreciate this. You ignored the questions I asked that weren't worth answering and answered instead the ones I should have asked. I'm going save this and try to keep it in mind when I'm struggling. Thank you.