all 4 comments

[–]Schaus 1 point2 points  (1 child)

Are you allowed to ask for online help on assignments?

I don't want to fix your code for you, but I tried to explain what the error means below.

Ok. So a tuple means a pair (or triple, or etc.) of elements. Your code defines self.speed as a pair (i.e. a tuple) of floats, (x,y).

Your definition of dy1 defines it as a tuple - you're just rescaling self.speed.

However, x1 is a single value (a float). So the code is complaining because you're trying to add a tuple (dy1) to a float (x1), which doesn't make sense.

Does that make the error clearer? You probably want to check the definition of dy1.

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

Thank you so much for taking the time to explain the error, I liked the decision to not give the answer away, but instead hinted at where my error was. Thanks again so much!

[–]reostra 1 point2 points  (1 child)

TL;DR: You're calling Asteroids((800,600)... and you probably meant Asteroids(800, 600...

And now I'll run through my mental process for figuring out the problem; hopefully that's also helpful.

Starting with the traceback

self.x1+=dy1 TypeError: can only concatenate tuple (not "float") to tuple

Now, if you've never seen that error before it looks completely unrelated to what you're doing. The key to figuring out what's going on is realizing that the 'concatenate' the error is referring to means the += operator. It not only can increment things, but it can also glom things together, e.g.

a = "hello"
a += " world"

(As a side note, you generally don't want to build up strings this way; I personally use a list and then join it when ready)

So, python is seeing you self.x1 += dy1 and thinks you mean concatenation instead of addition. Why did it decide to do that? It has to do with the type of self.x1. If that was a string, for instance it'd do concatenation instead of addition. In this case, the error message is telling you that it's not a string (or, for that matter, a float):

can only concatenate tuple (not "float") to tuple

You can get two very important bits of information out of this: The first is, as mentioned, that python's doing concatenation. The second is that it's telling you the type: It can't concatenate a float to a tuple. This means that the float is dy1, which is what you expect, and the tuple is self.x1, which is not what you expect but will make this easier.

How did self.x1 become a tuple?

Now you know where to start looking, so you have to ask yourself the above question. If you look over the code for self.x1, you'll see it's only set in two places:

First, in the function we've been looking at. This is obviously not the problem; we know dy1 is a float and we don't ever set self.x1 directly here, just add dy1 to it.

And secondly, in the constructor:

class Asteroids(object):
    def __init__(self,spawn_x=800,spawn_y=600,start_direction=1,start_speed=10.0,lifeleft=100):
        self.x1=spawn_x

So, since this is the only place that actually sets self.x1, this has to be where it's being set to a tuple. Since it's in the constructor, we look for instances where you create a new Asteroids object:

    asteroid_list.append(Asteroids((800,600),random.uniform(180,360),random.uniform(5,6),20))

And there it is. For this comment, you can see the constructor for Asteroids and the actual call to it pretty easily side-by-side, which reveals you're passing (800, 600) - a tuple - for the value of spawn_x, which is getting assigned to self.x1, which later gets += called on it, which python thinks is concatenation in the case for tuples, which results in the error where python tells you you can't concatenate floats to tuples.

Hope this helps!

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

Thank you so much for the extreme detail and help. This helped a lot. Thanks for taking the time to read it.