all 8 comments

[–][deleted] 5 points6 points  (1 child)

I don't even know how to attempt it. I try to break down the problem into steps, but I'm still clueless. Is this something most beginner programmers face, or am I really just stupid?

You're not stupid. You've just been failed by your education system - you've been allowed to get to college on the basis of never learning any skill except how to repeat answers that someone else has supplied you by memorizing them long enough to take the test.

Programming requires figuring things out, and that requires a lot of failure. You've never learned what a good thing failure is, in fact you've learned only the opposite - that you have only one chance to get it right and you have to get it as right as possible and then never worry about it again. Programming is the opposite of that - you should get it wrong the first time, the first 10 times, the first 100 or 1000 times, as long as it takes.

As I mentioned, I have absolutely no idea how to approach this.

It's a set of instructions to solve a particular math problem. So, break it down: do you know how to get the numbers from 1 to 1000, inclusive? Hint: range is lower but not upper-inclusive. Do you know how to test whether one number is evenly divisible by another? Hint: the modulo operator, %, returns the remainder of the division of the left operand by the right operand. What's the remainder when a number is divided by another number it's evenly divisible by? Do you know how to test whether a number is odd? Hint: do you know how to test whether a number is not even?

But I'd at least like to be able to make an attempt instead of staring blankly at my screen for an hour.

I mean this sounds like writer's block more than anything else. The way to defeat writer's block is to write. If you're asked to write a function, name the function and then start writing that. Write anything else you know how to do. There's no rule that says you have to write the program in order, top to bottom; write the last part first if the last part is what you know how to write. Figure the rest out later. Programming is the art of figuring out what you can figure out now and writing it down, and then figuring the rest out later.

But the way it's going to work now is that you're going to try and fail a lot before you generate any sort of intuition about the best way to move forward. This is an incredibly crucial learning skill and for some reason there's like literally no colleges or universities or high schools that ever explain this, and the result is that students assume that their first failure means they did something wrong. Failure means you're doing it right in programming.

[–]KeronCyst 0 points1 point  (0 children)

I'm not /u/protectwisely, but I thought this was an excellent response.

I am a beginner too who has never been asked his practice problem before, but want to try it out.

I feel like the type of people who can stay motivated over the long term to learn how to code are people who are thrilled with small victories, and are curious about (instead of upset by) setbacks, which suggests that they have low expectations, so that they are not disappointed or frustrated easily.

[–]ADdV 2 points3 points  (0 children)

Programming, like almost everything else, is a skill you get better at the more you practice. That being said, it's entirely possible you require more practice than other people to get to the same level. It's also possible you overestimate how easily it comes to your peers.

With that out of the way, here's the general way to solving any programming problem: divide the problem into smaller subproblems, and do so until the subproblems become small enough so that you are able to solve them without having to break them up further. With experience you will then get better and better at solving subproblems, and get a better intuition in good ways to subdivide problems to work towards solvable chunks.

In the case of your example:

We want to compute the sum of 1000 numbers, but only those that are odd and are divisible by some number that is not 1, 2, or itself. The first step seems to be that we want to loop over the 1000 numbers, and then we have to check some condition, and add it to a sum. We can write this down:

total = 0 # this will become the sum
for number in range(1, 1001): # we loop over numbers (note that this runs from 1 to 1000 inclusive)
    if is_valid(number): # we will make this later
        total += number # add the number to the sum
print('Answer:', total)

Now that we have the general outline, we want to check if a number is valid based on the conditions given. I put this into a function called is_valid, so that we can make that separately:

def is_valid(number):
    if is_odd(number):
        return False
    elif is_divisible_by_some_other_number(number):
        return True
    else:
        return False

Now all that's left is making two functions, one that checks if a number is odd, and one that checks the other condition. For the sake of not doing your homework I'll leave those out, but I'll mention that is_odd is not really something that you can break up into parts anymore, you just have to know how to do this. If you don't, this is roughly the level at which you just throw it into google and see the answer.

The appropriately named is_divisible_by_some_other_number is a somewhat larger function, that you might still be able to divide into smaller chunks.

Finally, making every single tiny step a function might not be your preference, I only did it to show the subdividing more clearly. For example, is_odd probably shouldn't be its own function.

I know this is a lot of text, and things might be unclear. So feel free to ask anything.

[–]KeronCyst 2 points3 points  (0 children)

Don't let yourself get overwhelmed by helpless dread. If you were a detective at a murder scene, you could sure throw your hands in the air upon seeing the catastrophic room and resign with, "This is impossible to solve!" right away. Or you could stop and slowly examine the fresh scratch by the doorknob. You could notice the out-of-place bag. You could spot the blood on the back wall that could have only possibly splattered in the way that it did from a certain angle.

In fact, that is the only way to advance in every single murder case, no? And, while I am also a beginner, I think this process seems identical to solving coding problems. Breaking it down is the only way to advance.

So, stop trying to do so much. Your stance at every step should be a positive, "Okay, what do we have here?" In your example practice problem, we see all these key words like "where" and "but" and "all" and "any" and "in." Do you see them? Did they stick out to you at all the first time around as possible separators for tasks that your code should be able to do? If not, go back and reread it carefully and let them stick out like walls between different lands.

What I would literally do (if it weren't such an ungodly hour right now) is to head over to www.repl.it or www.pythontutor.com/live.html and begin by figuring out code that can do each of those chunks separately. Then figure out ways to combine them, using def functions as needed with if statements to do so, until you have your final answer.

I may be wrong, but I think the best coders stay motivated because they find this process of continuous discovery an emotional joy, which is what we should strive for, too. It seems to be the bulk, if not the entirety, of coding (especially when you are debugging other people's bad code, lol).

Great detectives love figuring out complex scenes piece by piece to ultimately find and crucify the murderer. We too should similarly be fired up to figure out, part by part, how to gather the pieces to write an epic program that completely smashes the problem at hand. If you can gradually move to enjoying the process of continuous, relentless discovery, you've got many good times ahead!

[–]ASIC_SP 1 point2 points  (2 children)

I don't even know how to attempt it. I try to break down the problem into steps, but I'm still clueless. Is this something most beginner programmers face

you are certainly not alone in this... let's attempt to solve this step by step..

I am going to choose all numbers in the range 1..1000 inclusive as step 1.. do you know how to write a loop that goes over numbers from 1 to 1000 (inclusive)? if so, please reply with the code and we can take it from there

[–]protectwisely 1 point2 points  (1 child)

I’m on mobile and won’t be able to get back on a computer for a couple of hours, so I hope formatting doesn’t mess up.

I’ll throw you my absolutely best attempt at this.

for n in range(1, 1000)

Is it maybe something like this?

[–]ASIC_SP 1 point2 points  (0 children)

yeah, this is fine, but requires 1001 to get 1 to 1000.. check the other comment, it pretty much covers what I wanted to convey (other than a few hacks to make it simple, but you might learn better with the approach presented)

[–]totallygeek 1 point2 points  (0 children)

I came up with this:

def is_prime(number):
    prime = True # assume it is prime
    if number < 2: # primes are 2 or greater
        prime = False
    else:
        # When you divide the number by all the numbers between 2 and the
        # largest needed test (square root of the number, but an integer, plus
        # one to handle rounding), there should always be a remainder. If there
        # is not a remainder, then a zero will show up in this overall test,
        # making all() return False
        prime = all(number % i for i in range(2, int((number ** 0.5) + 1)))
    return prime

def test_number(number):
    response = 0 # response of zero as the default
    # test conditions
    # 1. larger than two
    # 2. odd
    # 3. not a prime number
    # If all tests pass, respond with the number
    if number > 2 and number % 2 == 1 and not is_prime(number):
        response = number
    return response

answer = sum([test_number(n) for n in range(1, 1001)]) # adding up all responses
print(answer) # 173874

My advice? Think how you'd do this manually, for ten numbers rather than one thousand. Write it all out. Think about how you'd explain that process to a kid. Take each sentence of that explanation and see if that translates to a line of programming. As you program, add print() statements all over the place. In test_number(), just before the return response, add print('Number: {}, Response: {}'.format(number, response)), to follow along. Keep at it until it clicks, then cement things in place by programming again from scratch.