Python - AttributeError: 'str' object has no attribute 'append' - python

I keep receiving this error when I try to run this code for the line "encoded.append("i")":
AttributeError: 'str' object has no attribute 'append'
I cannot work out why the list won't append with the string. I'm sure the problem is very simple Thank you for your help.
def encode(code, msg):
'''Encrypts a message, msg, using the substitutions defined in the
dictionary, code'''
msg = list(msg)
encoded = []
for i in msg:
if i in code.keys():
i = code[i]
encoded.append(i)
else:
encoded.append(i)
encoded = ''.join(encoded)
return encoded

You set encoded to string here:
encoded = ''.join(encoded)
And of course it doesn't have attribute 'append'.
Since you're doing it on one of cycle iteration, on next iteration you have str instead of list...

>>> encoded =["d","4"]
>>> encoded="".join(encoded)
>>> print (type(encoded))
<class 'str'> #It's not a list anymore, you converted it to string.
>>> encoded =["d","4",4] # 4 here as integer
>>> encoded="".join(encoded)
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
encoded="".join(encoded)
TypeError: sequence item 2: expected str instance, int found
>>>
As you see, your list is converted to a string in here "".join(encoded). And append is a method of lists, not strings. That's why you got that error. Also as you see if your encoded list has an element as integer, you will see TypeError because, you can't use join method on integers. Better you check your all codes again.

Your string conversion line is under the else clause. Take it out from under the conditional, and the for loop so that it's the last thing done to encoded. As it stands, you are converting to a string halfway through your for loop:
def encode(code, msg):
'''Encrypts a message, msg, using the substitutions defined in the
dictionary, code'''
msg = list(msg)
encoded = []
for i in msg:
if i in code.keys():
i = code[i]
encoded.append(i)
else:
encoded.append(i)
# after all appends and outside for loop
encoded = ''.join(encoded)
return encoded

You are getting the error because of the second expression in you else statement.
''.join(encoded) returns a string that gets assigned to encoded
Thus encoded is now of type string.
In the second loop you have the .append(i) method in either if/else statements which can only be applied to lists and not strings.
Your .join() method should appear after the for loop right before you return it.
I apoligise if the above text does not appear right. This is my first post and I still trying to figure out how this works.

Related

`TypeError: 'str' object is not callable` when a decorator function is called

I get a TypeError: 'str' object is not callable error when a decorator function is caleld. E.g. I
call the function msgReturnAsList, which is actually meant to return a list and therefore I do not understand why is it throwing an error that a str object is not callable.
I read at FreeCodeCamp that this TypeError occurs mainly in two occasions, neither of which has anything to do with my case:
1."If You Use str as a Variable Name in Python"
2. "If You Call a String Like a Function in Python"
Can somebody clarify what is the logic behind this and how do I get msgReturnAsList to return the string converted to upper by wrapThis and then converted to a list by the problematic decorator function msgReturnAsList?
def wrapThis(a):
a = str(a).upper()
return a
#wrapThis
def msgReturnAsList(msg):
msg = list(msg)
return msg
b = "Convert to upper and output it as a list of letters."
print(msgReturnAsList(b))
I tired changing the list to string, interestingly the error remains the same.
A decorator method should return a method:
def wrapThis(func):
def wrapper_func(msg):
msg = str(msg).upper()
return func(msg)
return wrapper_func
#wrapThis
def msgReturnAsList(msg):
msg = list(msg)
return msg
b = "Convert to upper and output it as a list of letters."
print(msgReturnAsList(b))
How to Create and Use Decorators in Python With Examples

How to check if some datatype is string or list in python?

I'm trying to add a check here that if the receiver is just a string. then convert that into list else just pass.
if type(receiver) == str:
receiver=[receiver]
error:
TypeError: 'str' object is not callable
You can check the type of an instance with the following.
if isinstance(receiver, str):
# do something if it is a string
If you just need to check rather it is not a string:
if not isinstance(receiver, str):
# do something if it is not a string
Look at this tutorial to learn more about the function.
a = '123'
print(str(a))
print(type(a))

Conversion From String To Int

I'm communicating with a modem via COM port to recieve CSQ values.
response = ser.readline()
csq = response[6:8]
print type(csq)
returns the following:
<type 'str'> and csq is a string with a value from 10-20
For further calculation I try to convert "csq" into an integer, but
i=int(csq)
returns following error:
invalid literal for int() with base 10: ''
A slightly more pythonic way:
i = int(csq) if csq else None
Your error message shows that you are trying to convert an empty string into an int which would cause problems.
Wrap your code in an if statement to check for empty strings:
if csq:
i = int(csq)
else:
i = None
Note that empty objects (empty lists, tuples, sets, strings etc) evaluate to False in Python.
As alternative you can put your code inside an try-except-block:
try:
i = int(csq)
except:
# some magic e.g.
i = False

Python: slice: TypeError: cannot concatenate 'str' and 'int' objects

I'm trying to write a module that searches for a key string in a target string and outputs the starting points of any matches. I can write an iterative module that achieves this, but I'm attempting to do it with recursion (the tutorial I'm using deals with recursion and iteration in this lesson, so I figure I should try both) and running into some trouble.
def substringmatchrecursive(target, key):
"""returns a tuple of the starting points of matches of the key string in the target string using a recursive function"""
from string import find
position = find(target, key) #position of the match
answer=() #will be outputted
if position == -1:
return 'No match'
else:
while position != 1:
answer = answer + (position, )
position = substringmatchrecursive(target[position+1: ], key)
return answer
loading the module and entering
substringmatchrecursive("fjdkakfjdslkfajfksja", "a")
which should give me a tuple of length 3, instead gives me an error
Traceback (most recent call last):
.....
position = substringmatchrecursive(target[position+1: ], key)
TypeError: cannot concatenate 'str' and 'int' objects
I'd assume that find() would output an integer, so position+1 should work. What is going on here?
According to following code, substringmatchrecursive returns str object ('No match') if it does not find a key.
if position == -1:
return 'No match'
And that str object is assigned to position:
position = substringmatchrecursive(target[position+1: ], key)
Make the function return a tuple consistently. (a predicate used in the while loop should be adjusted accordingly, or while should be gone if you want recursion, ...).
And use different name for position to avoid name collision.

Python: 'str' object is not callable

I have the following code
f = open('BigTestFile','w');
str = '0123456789'
for i in range(100000000):
if i % 1000000 == 0:
print(str(i / 1000000) + ' % done')
f.write(str)
f.close()
When I run it, I get this TypeError:
Traceback (most recent call last):
File "gen_big_file.py", line 8, in <module>
print(str(i / 1000000) + ' % done')
TypeError: 'str' object is not callable
Why is that? How to fix?
Call the variable something other than str.
It is shadowing the str built in function.
It's because you overrode the function str on line 3.
str() is a builtin function in Python which takes care of returning a nice string representation of an object.
Change line 3 from
str = '0123456789'
to
number_string = '0123456789'
You overwrote str which is normally a constructor for strings.
You could just change this line to "{} % done".format(i) if you really don't want to change it.
And if you insist on overwriting the str class instantiator with an actual string then replacing str(i) with "".__class__(i) would fix the error.
First of all, if you want to access the ith element of something, you need to use [i] and not (i). And second, as the others already mentioned, don't override str, the function to obtain any object's string representation.

Categories