TypeError: Can't convert 'int' object to str implicitly

T

tunacubes

Hey,

Let me explain what my program is supposed to do...

I am using a macro program in conjunction with a python script I am writing.. The macro inputs data into a database we use at my job, blah blah blah.

The script asks how many numbers (devices) you need to enter. Next, it asksyou to input the device numbers. When you input them, it creates a list with all of the devices. I then tell it to go into the script of the Macro (firstdev.ahk) that will run on the back-end, and replace the word "device" with the first device in the list. It then should execute the Macro, change the device number back to the word "Device" for future use, and then deletethe first number from the list. It will repeat as long as there are numbers in the list.

The error I receive is "TypeError: Can't convert 'int' object to str implicitly" when it tries to put the device into the macro script. It worked finewhen I just had it input one device into the script without the use of lists, but for whatever reason, using a list does not play nice with replacingthe words "Device" with the number from the list. Here is my script. I will give you up until the part that the error occurs, as everything afterwords is pointless.

I am fairly new to python, so if anything looks screwed up or like I am an idiot, it is because I am.

import fileinput, sys, os
devlist = []
maxdev = int(input("How many devices to add: "))
curdev = int("0")
while curdev < maxdev:
try:
Number = int(input("Enter Device number: "))
devlist.append(Number)
curdev = curdev + 1
except ValueError:
print("Please enter a valid number")
ready = 0
while ready != "Y" and ready != "y" and ready != "yes" and ready !="YES" and ready != "ready" and ready != "Ready":
try:
ready = input("Confirm when you are ready ")
except ValueError:
print("shit broke. ")
##This next step will seek out the word Device within firstdev.ahk, and replace with devlist[0]
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace("device", devlist[0])
sys.stdout.write(line)
##next step runs firstdev.ahk
os.system('firstdev.ahk')
##next step is replacing devlist[0] with "device"
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace(devlist[0], "device")
sys.stdout.write(line)
del devlist[0] #deleting the first item from the list. next steps will repeat.


Thanks in advance.
 
P

Peter Otten

Hey,

Let me explain what my program is supposed to do...

I am using a macro program in conjunction with a python script I am
writing. The macro inputs data into a database we use at my job, blah blah
blah.

The script asks how many numbers (devices) you need to enter. Next, it
asks you to input the device numbers. When you input them, it creates a
list with all of the devices. I then tell it to go into the script of the
Macro (firstdev.ahk) that will run on the back-end, and replace the word
"device" with the first device in the list. It then should execute the
Macro, change the device number back to the word "Device" for future use,
and then delete the first number from the list. It will repeat as long as
there are numbers in the list.

The error I receive is "TypeError: Can't convert 'int' object to str
implicitly" when it tries to put the device into the macro script.

Python is trying hard to give you a meaningful error message and shows the
line causing the error in the traceback. It pays to read carefully -- or to
post it here if it doesn't make sense to you.
devlist = [] ....
Number = int(input("Enter Device number: "))
devlist.append(Number) ....
line = line.replace(devlist[0], "device")

devList is a list of integers, and devlist[0] is thus an int.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't convert 'int' object to str implicitly

Implicitly? So let's try and convert the int /explicitly/ .
'foo device bar\n'

No error, but probably still not what you expected. Can you sort it out
yourself?
I am fairly new to python, so if anything looks screwed up or like I am an
idiot, it is because I am.

I like to see a bit of self-deprecation now and then, but on this list
complete tracebacks find even more love ;)
 
C

Chris Angelico

Hey,
The error I receive is "TypeError: Can't convert 'int' object to str implicitly" when it tries to put the device into the macro script. It worked fine when I just had it input one device into the script without the use of lists, but for whatever reason, using a list does not play nice with replacing the words "Device" with the number from the list. Here is my script. I will give you up until the part that the error occurs, as everything afterwords is pointless.

I am fairly new to python, so if anything looks screwed up or like I am an idiot, it is because I am.

Welcome to Python. One thing that you'll quickly learn is that the
full traceback is REALLY helpful; in this case, there won't be much
traceback, but at least you'll get the line number. I'm looking at
this line as being the culprit:
line = line.replace("device", devlist[0])

All you need to do is convert that to a string:
line = line.replace("device", str(devlist[0]))
and that should fix your problem. But while I'm here, may I offer a
few other tips?

(By the way, I'm going to assume you're using Python 3 here, because
otherwise your "confirm when ready" would be bombing. But it helps to
say what version you're using.)
import fileinput, sys, os
devlist = []
maxdev = int(input("How many devices to add: "))
curdev = int("0")

Just 'curdev = 0' would work here. No need to convert a string to an
integer - just use a literal integer.
while curdev < maxdev:

UI suggestion: Let the user keep on inputting device numbers until
some kind of sentinel (eg a blank line), unless it makes really good
sense to ask for the number up-front.
try:
Number = int(input("Enter Device number: "))
devlist.append(Number)
curdev = curdev + 1
except ValueError:
print("Please enter a valid number")

You can save the hassle of maintaining curdev by simply looking at
len(devlist) - that is, change your condition to "while len(devlist) <
maxdev".
ready = 0
while ready != "Y" and ready != "y" and ready != "yes" and ready != "YES" and ready != "ready" and ready != "Ready":

Here's a really cool tip. You can simply check set membership:

while ready not in {"Y","y","yes","YES","ready","Ready"}:

But I'd be inclined to make the UI a bit tighter here and make it
something like:

ready = input("Confirm when you are ready <y/N>: ")

and then just look for either "Y" or "y", nothing more. But that's up
to you. You know who's going to use this program, I don't. (The
capitalized N representing that the default is No is a convention you
may or may not want to follow.)
try:
ready = input("Confirm when you are ready ")
except ValueError:
print("shit broke. ")

Drop the try/except; if there's something wrong (and, btw, I'm not
sure what circumstances would trigger a ValueError here - maybe
someone else knows of something?), just let the exception terminate
the program. There's nothing useful to do here anyway :)
##This next step will seek out the word Device within firstdev.ahk, and replace with devlist[0]
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace("device", devlist[0])
sys.stdout.write(line)

You're reading a single file with constant name here. Save yourself
some trouble: just open the file directly.

for line in open("firstdev.ahk"):
print(line.replace("device", str(devlist[0])))

Though I'm not sure why you want to write to stdout here. Were you
intending to write back to another file? I'm getting a bit lost in
your code here. My understanding of your intentions, from your
comments, is that you actually want to repeat most of the code from
here on for each device number entered - that strongly suggests a
'for' loop bracketing the whole thing. Is that what you meant this to
do? Currently, it'll get to the 'del' at the bottom, and then just
terminate.
##next step runs firstdev.ahk
os.system('firstdev.ahk')
##next step is replacing devlist[0] with "device"
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace(devlist[0], "device")
sys.stdout.write(line)

And here you repeat everything from above. Again, not sure what you're
intending to do here.
del devlist[0] #deleting the first item from the list. next steps will repeat.

The steps won't repeat by themselves, so this is where I'm thinking
you actually want a for loop.

I hope you don't take this the wrong way, as I feel now (on skimming
over this email prior to sending) that I've kinda pulled your code to
pieces a bit! It's just advice, just suggestions; this is your code
and nobody else's. You may very well disagree with any or all of what
I've said, and that's to be expected. It's also a great way to get
discussion going, and discussion is one of the best ways for everyone
to learn :)

Chris Angelico
 
C

Chris Angelico

##This next step will seek out the word Device within firstdev.ahk, and replace with devlist[0]
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace("device", devlist[0])
sys.stdout.write(line)
##next step runs firstdev.ahk
os.system('firstdev.ahk')
##next step is replacing devlist[0] with "device"
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace(devlist[0], "device")
sys.stdout.write(line)

I've checked out what fileinput.input() is doing here (ought to have
done that earlier, sorry!) and I now understand this block of code
more. You're replacing that word _in the file, on disk_, and then
making the inverse replacement. This strikes me as dangerous; if
anything happens to your process in the middle, the file will be
damaged on disk. I would STRONGLY recommend rewriting this to use some
other file - for instance, a temporary file. I haven't looked into the
details, as I haven't actually done this lately in Python, but you
should be able to use tempfile.NamedTemporaryFile(delete=False) [1],
write to it, make it executable, run it, and unlink it. That way,
you're creating a temporary file to run, not running the original.
This is semantically different from your code, but I think it'd be a
lot safer.

[1] http://docs.python.org/3.3/library/tempfile.html#tempfile.NamedTemporaryFile

ChrisA
 
T

tunacubes

(e-mail address removed) wrote:


Hey,

Let me explain what my program is supposed to do...

I am using a macro program in conjunction with a python script I am
writing. The macro inputs data into a database we use at my job, blah blah


The script asks how many numbers (devices) you need to enter. Next, it
asks you to input the device numbers. When you input them, it creates a
list with all of the devices. I then tell it to go into the script of the
Macro (firstdev.ahk) that will run on the back-end, and replace the word
"device" with the first device in the list. It then should execute the
Macro, change the device number back to the word "Device" for future use,
and then delete the first number from the list. It will repeat as long as
there are numbers in the list.

The error I receive is "TypeError: Can't convert 'int' object to str
implicitly" when it tries to put the device into the macro script.



Python is trying hard to give you a meaningful error message and shows the

line causing the error in the traceback. It pays to read carefully -- or to

post it here if it doesn't make sense to you.


devlist = []
...

Number = int(input("Enter Device number: "))
devlist.append(Number)

...

line = line.replace(devlist[0], "device")



devList is a list of integers, and devlist[0] is thus an int.



Traceback (most recent call last):

File "<stdin>", line 1, in <module>

TypeError: Can't convert 'int' object to str implicitly



Implicitly? So let's try and convert the int /explicitly/ .



'foo device bar\n'



No error, but probably still not what you expected. Can you sort it out

yourself?


I am fairly new to python, so if anything looks screwed up or like I am an
idiot, it is because I am.



I like to see a bit of self-deprecation now and then, but on this list

complete tracebacks find even more love ;)

Thank you, Peter. This was a tremendous help. Got it working.
 
T

tunacubes

##This next step will seek out the word Device within firstdev.ahk, and replace with devlist[0]
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace("device", devlist[0])
sys.stdout.write(line)

##next step runs firstdev.ahk
os.system('firstdev.ahk')

##next step is replacing devlist[0] with "device"
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace(devlist[0], "device")
sys.stdout.write(line)



I've checked out what fileinput.input() is doing here (ought to have

done that earlier, sorry!) and I now understand this block of code

more. You're replacing that word _in the file, on disk_, and then

making the inverse replacement. This strikes me as dangerous; if

anything happens to your process in the middle, the file will be

damaged on disk. I would STRONGLY recommend rewriting this to use some

other file - for instance, a temporary file. I haven't looked into the

details, as I haven't actually done this lately in Python, but you

should be able to use tempfile.NamedTemporaryFile(delete=False) [1],

write to it, make it executable, run it, and unlink it. That way,

you're creating a temporary file to run, not running the original.

This is semantically different from your code, but I think it'd be a

lot safer.



[1] http://docs.python.org/3.3/library/tempfile.html#tempfile.NamedTemporaryFile



ChrisA

Thank you, Chris! I got it working and am going to take your advice on the tempfile idea. I actually ran into the problem you were referring to, and kept the .ahk files backed up elsewhere for when this situation arose. I appreciate the help!
 
C

Chris Angelico

I've checked out what fileinput.input() is doing here (ought to have

done that earlier, sorry!) and I now understand this block of code

more. You're replacing that word _in the file, on disk_, and then

making the inverse replacement. This strikes me as dangerous; if

anything happens to your process in the middle, the file will be

damaged on disk. I would STRONGLY recommend rewriting this to use some

other file - for instance, a temporary file. I haven't looked into the

details, as I haven't actually done this lately in Python, but you

should be able to use tempfile.NamedTemporaryFile(delete=False) [1],

write to it, make it executable, run it, and unlink it. That way,

you're creating a temporary file to run, not running the original.

This is semantically different from your code, but I think it'd be a

lot safer.

Thank you, Chris! I got it working and am going to take your advice on the tempfile idea. I actually ran into the problem you were referring to, and kept the .ahk files backed up elsewhere for when this situation arose. I appreciate the help!

Awesome!

Hey, you want to know an easy way to show your appreciation for the
people who answer your questions? It's really simple:

Step 1: Don't use Google Groups to post.
Step 2: Profit!

Have a look at the quoted text in your responses. See how it's
double-spaced and really obnoxious? That's not your fault, it's
because Google Groups is buggy. There are plenty of other ways to read
and post; I personally have subscribed to the mailing list and read it
using Gmail, and there are a variety of other ways too. If you _must_
use Google Groups, check out this page for some recommendations on how
to not offend people.

http://wiki.python.org/moin/GoogleGroupsPython

There are a number of non-G-rated terms going around that fairly
accurately describe what Google Groups posts look like, but since I
prefer milder language, I'll just repeat the word "obnoxious", as it
carries all the meaning I need.

ChrisA
 
D

Dave Angel

##This next step will seek out the word Device within firstdev.ahk, and replace with devlist[0]
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace("device", devlist[0])
sys.stdout.write(line)
##next step runs firstdev.ahk
os.system('firstdev.ahk')
##next step is replacing devlist[0] with "device"
for line in fileinput.input(["firstdev.ahk"], inplace=True):
line = line.replace(devlist[0], "device")
sys.stdout.write(line)

I've checked out what fileinput.input() is doing here (ought to have
done that earlier, sorry!) and I now understand this block of code
more. You're replacing that word _in the file, on disk_, and then
making the inverse replacement. This strikes me as dangerous; if
anything happens to your process in the middle, the file will be
damaged on disk. I would STRONGLY recommend rewriting this to use some
other file - for instance, a temporary file. I haven't looked into the
details, as I haven't actually done this lately in Python, but you
should be able to use tempfile.NamedTemporaryFile(delete=False) [1],
write to it, make it executable, run it, and unlink it. That way,
you're creating a temporary file to run, not running the original.
This is semantically different from your code, but I think it'd be a
lot safer.

[1] http://docs.python.org/3.3/library/tempfile.html#tempfile.NamedTemporaryFile

ChrisA

fileinput.Fileinput class already creates the temp file when you specify
inplace=True

If it didn't, I'd also have to point out the hazards of doing in-place
updates in a text file where the new data and old is a different length.

There still may be reasons to make an explicit backup, but I don't know
what they are.
 
C

Chris Angelico

fileinput.Fileinput class already creates the temp file when you specify
inplace=True

If it didn't, I'd also have to point out the hazards of doing in-place
updates in a text file where the new data and old is a different length.

There still may be reasons to make an explicit backup, but I don't know what
they are.

That's true if something goes wrong during the actual writing of the
file only. But if the process bombs in the middle of the execution
phase (which in the Python script is a single os.system() call), then
the file will have been one-way changed on the disk - hence,
"damaged". The explicit temporary file (and executing the temp file)
is a much safer way to do it.

ChrisA
 
D

Dave Angel

That's true if something goes wrong during the actual writing of the
file only. But if the process bombs in the middle of the execution
phase (which in the Python script is a single os.system() call), then
the file will have been one-way changed on the disk - hence,
"damaged". The explicit temporary file (and executing the temp file)
is a much safer way to do it.

Only two of those sentences makes sense to me. I have no idea what
"execution phase" means, and don't know what would be done via an
os.system() call. I don't know what "one-way change" means

If I were specifying the fileinput stuff, I'd have said the new data
should be written to the temp file, so that at no time was the original
file in an in-between state.
 
C

Chris Angelico

Only two of those sentences makes sense to me. I have no idea what
"execution phase" means, and don't know what would be done via an
os.system() call. I don't know what "one-way change" means

If I were specifying the fileinput stuff, I'd have said the new data should
be written to the temp file, so that at no time was the original file in an
in-between state.

Here's a massive simplification of the OP's program:

1. Build a list of device IDs
2. Edit the file "firstdev.ahk" and replace all instances of "device"
with the device ID
3. Execute the now-edited firstdev.ahk using os.system()
4. Reverse the edit of firstdev.ahk, replacing all instances of the
device ID with the word "device".

Apart from the risk of accidentally changing back something that
wasn't changed in the first place (which the OP may know to be
impossible, eg if the macro file has no numbers in it), this has the
risk that a computer failure in step 3 will leave the file on disk in
its edited state. That's what I'm concerned about. By writing the
modified .ahk content to a different file and then executing the other
file, he would avoid editing the template at all. It'd also then be
multi-process safe, for what that's worth.

ChrisA
 
D

Dave Angel

Here's a massive simplification of the OP's program:

1. Build a list of device IDs
2. Edit the file "firstdev.ahk" and replace all instances of "device"
with the device ID
3. Execute the now-edited firstdev.ahk using os.system()
4. Reverse the edit of firstdev.ahk, replacing all instances of the
device ID with the word "device".

Apart from the risk of accidentally changing back something that
wasn't changed in the first place (which the OP may know to be
impossible, eg if the macro file has no numbers in it), this has the
risk that a computer failure in step 3 will leave the file on disk in
its edited state. That's what I'm concerned about. By writing the
modified .ahk content to a different file and then executing the other
file, he would avoid editing the template at all. It'd also then be
multi-process safe, for what that's worth.
OK, thanks. That makes perfect sense. Somehow I missed that it was the
altered file that was being used as a script. I just assumed it was
like a config file for some program, where the name is hardwired.
 
Joined
Mar 9, 2020
Messages
1
Reaction score
0
The TypeError: can't convert 'int' object to str implicitly is generated because '+' (addition) does not work between an integer and a string. When concatenating strings with integers - you can't directly stick together a string and an integer. So, in order to resolve this problem, you have to explicitly parse the integer to a string by the str() built-in function string + str(number) or use formatting to format your output.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,479
Members
44,900
Latest member
Nell636132

Latest Threads

Top