I'm trying to make this code turn the prodname variable into an int value:
def prod_check(dirname):
prodname_to_prodnum = {}
fid2 = open('sample.txt','r')
line = fid2.readline()
line = line.strip()
pline = line.split(',')
prodname = (pline[0])[1:-1]
prodnum = prodname
prodname_to_prodnum[prodname] = prodnum
line = fid2.readline()
fid2.close()
but when I used "int(prodname)" I get an error
Try this instead of prodnum = prodname:
try:
prodnum = int(prodname)
except ValueError:
prodnum = None
print('prodname = ',prodname)
Lists in Python are 0-based, not 1-based. You've already broken the line into fields with split, so you should use prodnum = int(pline[0]) to get the first field.
Edit: I wish people would use copy/paste to put their code into the question, typos make all the difference.
I don't know why you're removing the first and last character from the number field, perhaps because you need to strip blanks from it? If so, try using prodnum = int(pline[0].strip()).
Related
while n == 1:
w = inputs.append(input('Enter the product code: '))
with open('items.txt') as f:
found = False
for line in f:
if w in line:
So this is the part of the code with the issue. After the last line a bunch of stuff happens which is irrelevant to the question. When i run it, i get the error:
if w in line:
TypeError: 'in ' requires string as left operand, not NoneType
I know it's because i need to convert w to a string somehow but i don't know what to do. Any help is appreciated.
input() already returns a string, so there is no need to convert it.
You have this:
w = inputs.append(input('Enter the product code: '))
You should be doing this in two steps, since you are assigning w to the return value of append(), rather than the return value of input() in this case. append() will always return None regardless of the user input, so w in your program will be assigned to None. Instead, try:
w = input('Enter the product code: ')
inputs.append(w)
In Python, I am getting 'TypeError: not all arguments converted during string formatting'
I am not sure why this is happening. This line is being highlighted as where the problem lies - data.append('%s,%s,%s'%line['code'],line['level'],line['target'],line['distancefromtarget']
Can anybody find the problem?
In case it helps, here is the other code around this line.
def updatestocklevel(quantity, stocklevel, code):
with open('stockcontrol.csv',newline='') as f:
for line in f:
if code in line:
data = line.split(",")
target = (data[2])
updatetarget = int(target) - int(stocklevel)
newlevel = stocklevel - quantity
stocklevel = str(stocklevel)
newlevel = str(newlevel)
updatetarget = str(updatetarget)
import sys
import csv
data=[]
code = code
newval= newlevel
newtlevel = updatetarget
f=open("stockcontrol.csv")
reader=csv.DictReader(f,fieldnames=['code','level', 'target', 'distancefromtarget'])
for line in reader:
if line['code'] == code:
line['level']= newval
line['distancefromtarget']= newtlevel
data.append('%s,%s,%s'%(line['code'],line['level'],line['target'],line['distancefromtarget']))
f.close()
f=open("stockcontrol.csv","w")
f.write("\n".join(data))
f.close()
Thank You.
You've got a tuple with 4 elements:
(line['code'],line['level'],line['target'],line['distancefromtarget'])
But only 3 substitution placeholders:
'%s,%s,%s'
When you try to format that, not all of the "arguments" (tuple elements) will be converted to strings for the formatting (hence the error). Either change the tuple to remove an element, or change the string being interpolated to add another field (e.g. '%s,%s,%s,%s').
Im trying to create a finite state machine that reads in the states, transitions, and the strings. I am trying to create it without objects. Everything works up till my for loops. However, as soon as the loop begins I get the error message:
line 42, in <module>
for I in len (Strings):
TypeError: 'int' object is not iterable
Why is this happening? Any tips would be appreciated.
Sfile = open("states.txt","r")
States = []
ReadLine = Sfile.readline()
while ReadLine != "":
A, B, C = ReadLine.split(",")
States.append((A, bool(int(B)), bool(int(C))))
ReadLine = Sfile.readline()
print States, "\n"
Sfile.close()
Tfile = open("transistions.txt","r")
Transitions = []
ReadLine = Tfile.readline()
while ReadLine != "":
ReadLine = ReadLine.rstrip()
Tran4, Tran5, Tran6 = ReadLine.split(",")
Transitions.append((Tran4, Tran5, Tran6))
ReadLine = Tfile.readline()
print Transitions
Tfile.close()
Strfile = open("strings2.txt","r")
Strings = []
ReadLine = Strfile.readline()
while ReadLine != "":
Readline = ReadLine.rstrip()
Strings.append(Readline)
ReadLine = Strfile.readline()
print Strings, '\n'
Strfile.close()
for I in len (Strings):
for C in Strings[I]:
Start = '0'
Current = Start
if C in Strings == '0':
Current = A
else:
Current = State
print Current...
My different text files contain:
states.txt
State2,1,0
State3,0,1
State4,1,0
transitions.txt
State1,0,State2
State2,1,State3
State3,0,State4
strings2.txt
10100101
1001
10010
You can't iterate over an integer. I think you meant to iterate over a range object range(len(Strings)). This will work because the range object is an iterable and the int is not.
You want i in range(len(Strings)). Len returns a whole number, like 13 -- in wants something like a vector. range(13) gives you a vector [0,1,2,3,4,5,6,7,8,9,10,11,12].
Quiz question: why is the last number 12?
You're trying to iterate over an integer, it should be
for I in range(len(Strings))
You will need to turn the number to a string as you cant pick out the first digit of an int. So str(1234)='1234' '1234'[0]='1'
len(s) gives you an integer, and you can't iterate over that. If you want to iterate over a collection of strings, use for s in strings.
you can't iterate over a number or any other singular object, you need a composite object like a list, to do that. In this case look like you want this
for words in Strings:
for C in words:
...
I'm sure this is a basic question, but I have spent about an hour on it already and can't quite figure it out. I'm parsing smartctl output, and here is the a sample of the data I'm working with:
smartctl 5.41 2011-06-09 r3365 [x86_64-linux-2.6.32-39-pve] (local build)
Copyright (C) 2002-11 by Bruce Allen, http://smartmontools.sourceforge.net
=== START OF INFORMATION SECTION ===
Device Model: TOSHIBA MD04ACA500
Serial Number: Y9MYK6M4BS9K
LU WWN Device Id: 5 000039 5ebe01bc8
Firmware Version: FP2A
User Capacity: 5,000,981,078,016 bytes [5.00 TB]
Sector Sizes: 512 bytes logical, 4096 bytes physical
Device is: Not in smartctl database [for details use: -P showall]
ATA Version is: 8
ATA Standard is: Exact ATA specification draft version not indicated
Local Time is: Thu Jul 2 11:24:08 2015 EDT
SMART support is: Available - device has SMART capability.
SMART support is: Enabled
What I'm trying to achieve is pulling out the device model (some devices it's just one string, other devices, such as this one, it's two words), serial number, time, and a couple other fields. I assume it would be easiest to capture all data after the colon, but how to eliminate the variable amounts of spaces?
Here is the relevant code I currently came up with:
deviceModel = ""
serialNumber = ""
lines = infoMessage.split("\n")
for line in lines:
parts = line.split()
if str(parts):
if parts[0] == "Device Model: ":
deviceModel = parts[1]
elif parts[0] == "Serial Number: ":
serialNumber = parts[1]
vprint(3, "Device model: %s" %deviceModel)
vprint(3, "Serial number: %s" %serialNumber)
The error I keep getting is:
File "./tester.py", line 152, in parseOutput
if parts[0] == "Device Model: ":
IndexError: list index out of range
I get what the error is saying (kinda), but I'm not sure what else the range could be, or if I'm even attempting this in the right way. Looking for guidance to get me going in the right direction. Any help is greatly appreciated.
Thanks!
The IndexError occurs when the split returns a list of length one or zero and you access the second element. This happens when it isn't finding anything to split (empty line).
No need for regular expressions:
deviceModel = ""
serialNumber = ""
lines = infoMessage.split("\n")
for line in lines:
if line.startswith("Device Model:"):
deviceModel = line.split(":")[1].strip()
elif line.startswith("Serial Number:"):
serialNumber = line.split(":")[1].strip()
print("Device model: %s" %deviceModel)
print("Serial number: %s" %serialNumber)
I guess your problem is the empty line in the middle. Because,
>>> '\n'.split()
[]
You can do something like,
>>> f = open('a.txt')
>>> lines = f.readlines()
>>> deviceModel = [line for line in lines if 'Device Model' in line][0].split(':')[1].strip()
# 'TOSHIBA MD04ACA500'
>>> serialNumber = [line for line in lines if 'Serial Number' in line][0].split(':')[1].strip()
# 'Y9MYK6M4BS9K'
Try using regular expressions:
import re
r = re.compile("^[^:]*:\s+(.*)$")
m = r.match("Device Model: TOSHIBA MD04ACA500")
print m.group(1) # Prints "TOSHIBA MD04ACA500"
Not sure what version you're running, but on 2.7, line.split() is splitting the line by word, so
>>> parts = line.split()
parts = ['Device', 'Model:', 'TOSHIBA', 'MD04ACA500']
You can also try line.startswith() to find the lines you want https://docs.python.org/2/library/stdtypes.html#str.startswith
The way I would debug this is by printing out parts at every iteration. Try that and show us what the list is when it fails.
Edit: Your problem is most likely what #jonrsharpe said. parts is probably an empty list when it gets to an empty line and str(parts) will just return '[]' which is True. Try to test that.
I think it would be far easier to use regular expressions here.
import re
for line in lines:
# Splits the string into at most two parts
# at the first colon which is followed by one or more spaces
parts = re.split(':\s+', line, 1)
if parts:
if parts[0] == "Device Model":
deviceModel = parts[1]
elif parts[0] == "Serial Number":
serialNumber = parts[1]
Mind you, if you only care about the two fields, startswith might be better.
When you split the blank line, parts is an empty list.
You try to accommodate that by checking for an empty list, But you turn the empty list to a string which causes your conditional statement to be True.
>>> s = []
>>> bool(s)
False
>>> str(s)
'[]'
>>> bool(str(s))
True
>>>
Change if str(parts): to if parts:.
Many would say that using a try/except block would be idiomatic for Python
for line in lines:
parts = line.split()
try:
if parts[0] == "Device Model: ":
deviceModel = parts[1]
elif parts[0] == "Serial Number: ":
serialNumber = parts[1]
except IndexError:
pass
so this piece of code is meant to take a line from a file and replace the certain line from the string with a new word/number, but it doesn't seem to work :(
else:
with open('newfile', 'r+')as myfile:
x=input("what would you like to change: \nname \ncolour \nnumber \nenter option:")
if x == "name":
print("your current name is:")
test_lines = myfile.readlines()
print(test_lines[0])
y=input("change name to:")
content = (y)
myfile.write(str.replace((test_lines[0]), str(content)))
I get the error message TypeError: replace() takes at least 2 arguments (1 given), i don't know why (content) is not accepted as an argument. This also happens for the code below
if x == "number":
print ("your current fav. number is:")
test_lines = myfile.readlines()
print(test_lines[2])
number=(int(input("times fav number by a number to get your new number \ne.g 5*2 = 10 \nnew number:")))
result = (int(test_lines[2])*(number))
print (result)
myfile.write(str.replace((test_lines[2]), str(result)))
f=open('newfile', 'r')
print("now we will print the file:")
for line in f:
print (line)
f.close
replace is a function of a 'str' object.
Sounds like you want to do something like (this is a guess not knowing your inputs)
test_lines[0].replace(test_lines[0],str(content))
I'm not sure what you're attempting to accomplish with the logic in there. looks like you want to remove that line completely and replace it?
also i'm unsure what you are trying to do with
content = (y)
the output of input is a str (which is what you want)
EDIT:
In your specific case (replacing a whole line) i would suggest just reassigning that item in the list. e.g.
test_lines[0] = content
To overwrite the file you will have to truncate it to avoid any race conditions. So once you have made your changes in memory, you should seek to the beginning, and rewrite everything.
# Your logic for replacing the line or desired changes
myfile.seek(0)
for l in test_lines:
myfile.write("%s\n" % l)
myfile.truncate()
Try this:
test_lines = myfile.readlines()
print(test_lines[0])
y = input("change name to:")
content = str(y)
myfile.write(test_lines[0].replace(test_lines[0], content))
You have no object known purely as str. The method replace() must be called on a string object. You can call it on test_lines[0] which refers to a string object.
However, you may need to change your actual program flow. However, this should circumvent the error.
You need to call it as test_lines[0].replace(test_lines[0],str(content))
Calling help(str.replace) at the interpreter.
replace(...)
S.replace(old, new[, count]) -> str
Return a copy of S with all occurrences of substring
old replaced by new. If the optional argument count is
given, only the first count occurrences are replaced.
Couldn't find the docs.