9/14 what is the problem?


#1

In task thare was a phrase “Try to do it on your own without using the ^ operator.” So I decided to take this challenge but my code does weird

first = "0b1110"
second = "0b101"
first = list(first)
second = list(second)
total = ["0b"]
first = first[2::]
second = second[2::]

index = 0

if len(first) > len(second):
  second = second.insert(0, '0')
elif len(first) < len(second):
  first = first.insert(0, '0')
else:
  pass

for x in first:
  if x == second[index]:
    total.append('0')
  else:
    total.append('1')
  index += 1

print total

and the problem “TypeError: ‘NoneType’ object has no attribute ‘getitem’”. How can I fix it??


#2

The type NoneType only has one value: None
And __getitem__ corresponds to the [] operator (…it gets an item)
So if that variable refers to None and you expect it to refer to something else, then you probably made a mistake and should look at where you last assigned to it

I also suggest that you never guess how something behaves, and instead find out (guessing how something behaves is probably how you obtained None, that something didn’t behave that way (nothing to indicate that it would, was there?))
This is done by looking up the documentation for that something, or perhaps testing it to see how it behaves but it’s weaker because you might not have understood it correctly and you haven’t received a promise of what it does


#3

I came here because I’m new to programming and (what a surprise) I go along the way of trial and error. Could you explain me how can I solve this trouble?


#4

By looking at what went wrong, comparing to what you meant, and adjusting the code to eliminate that difference.

So you’d start by identifying what you did that you can’t do. Otherwise you can’t fix it.


#5

Whilst it’s good that you’ve given us the error message that you’ve got, Python gives you a trace when it encounters an error that stops the program which includes the steps it took to arrive at that error as well as line references and other helpful troubleshooting info.

If you look at the traceback, and post a copy of it here, you ought to be able to figure out what part of your code Python doesn’t like, and which line(s) you need to fix. Posting a copy of it here will make it easier for us to help you with that, too. :slight_smile:


#6

Ok, here it is the full traceback

Traceback (most recent call last):
File “python”, line 19, in
TypeError: ‘NoneType’ object has no attribute ‘getitem


#7

Ok, so line 19 of your code is:

if x == second[index]:

so something on that line is not as Python and you are expecting it to be. :slight_smile:


#8

…If you get an error message saying you can’t divide by zero

Then you would hopefully agree, and then look at where you were getting the zero from, and considering what you meant and why you wouldn’t have a zero there, and changing the code to match.

This is no different.

If something is preventing you from going through those steps, then identify that, solve it, and then keep going. Maybe ask about that something. What are you missing to solve this yourself?


#9

Yeah, but I ducking don’t understand what is wrong!


#10

Let’s review what we know so far.

Your program runs fine, right up until Python encounters the following line:

if x == second[index]:

after which, you get a NoneType error. Specifically, the error is 'NoneType' object has no attribute 'getitem'.

Can you see where in that line Python is attempting to get a particular item from an object?

Are you, perhaps, trying to retrieve an item from a list?

:slight_smile:


#11

Sometimes finding a error is harder than just starting over. In that process, oftentimes the error will surface and jump right out. At any length, sometimes starting over gives us a chance to invent a different approach. From there we can go back to our first attempt and refactor.

>>> a = str(bin(0b101110))[2:]
>>> b = str(bin(0b101))[2:]
>>> m = len(a)
>>> n = len(b)
>>> if n > m:
	a, b = b, a

	
>>> b = '0' * abs(m - n) + b
>>> b
'000101'
>>> n = -m if m > n else -n
>>> for x in range(n, 0):
	c += '1' if a[x] != b[x] else '0'

	
>>> c
'101011'
>>> int(c, base=2)
43
>>> bin(int(c, base=2))
'0b101011'
>>> 

#12

True, but teaching people who are new to programming that they should just cut and run rather than debugging their code is imho bad form. We’re easily able to go back to square one and start over from scratch in this instance, but in a professional environment you’re not going to be able to do that a lot of the time.

The ability to debug and troubleshoot code is a necessary one, and as it happens the problem here isn’t a particularly difficult one to fix. It might take @quentas1 a bit of time to get to the root cause and fix it since they’re still learning Python, but doing so will be a valuable learning experience.

:slight_smile:


#13

I would consider it worse form to simply parrot what you said. As a beginner, it can’t hurt to try whatever approach gets the juices flowing. We didn’t say to throw out the baby with the bath water, but to just start from scratch and see how things unfold on a separate attempt. The OP is obviously testing a theory and hit a wall with a syntax error or exception.

We could walk them through the problem with a checklist of sorts, but you have already done that. And I don’t see my idea as bad form. It has relevance.


#14

Thanks to everyone, I guess I’ll come back to this problem when I get more experienced


#15

What’s causing your error here is actually quite straightforward to fix, and finding where it’s coming from is also quite simple.

If you want a hint as to where to start, look at the spoiler in my previous post. (You can click on the blurred text to reveal it.) :slight_smile:


#16

Looks like the problem is in this part:

if len(first) > len(second):
second = second.insert(0, ‘0’)
elif len(first) < len(second):
first = first.insert(0, ‘0’)
else:
pass

because I just supplemented it

if len(first) > len(second):
second = second.insert(0, ‘0’)
print second, first
elif len(first) < len(second):
first = first.insert(0, ‘0’)
print first, second
else:
pass

and now it (in addition to the previous problem) returns “None [‘1’, ‘1’, ‘1’, ‘0’]
Maybe this is because of insert, I havent studied it yet, just saw it at StackOverflow and decided to try


#17

second.insert() has no return value, hence None is being assigned. Treat that expression as a standalone statement…

second.insert(0, '0')

But there is a broader issue here that is not evident under the current conditions. What if the length difference is greater than 1? Witness in my earlier example that the length difference is 3. The code foresees this and allows for any difference in length. It just pads out the shorter string.

Notice also that above I used strings, and not lists. Strings are a convenient iterable in this situation. Also, we do not need to build up the first two characters of the string, (‘0b’) since the bin(int()) function combo, when given a base parameter will correctly interpret the value.


#18

Bingo! If you look at @mtf’s post above, he’s been kind enough to explain why you’re getting a None object back. :slight_smile:

Good that you’re looking at code elsewhere and then playing around with it, though. :+1: Excellent way to learn I find. :slight_smile:


#19

Is it possible to make method that always returns something not to return anything?


#20

There’s a contradiction in your question. Maybe you mean something else. Otherwise you already proved that impossibility.