Python writing int into file - python

I have a problem with python code and i don't know what to do, because im fairly new in it.
date_now1 = datetime.datetime.now()
archive_date1 = date_now1.strftime("%d.%m.%Y")
f1 = open(archive_date1, "r+")
print("What product do you wish to delete ?")
delate_product = str(input())
for line in f1.readlines():
if delate_product in line:
list = line
ready_product = list.split()
quantity_of_product = int(ready_product[1])
if quantity_of_product == 1:
del line
print("Product deleted")
else:
print("You have {} amounts of this product. How many do you want to delete ?".format(quantity_of_product))
x = int(input())
quantity_of_product = quantity_of_product - x
temporary = "{}".format(quantity_of_product)
print(type(temporary))
f1.write(temporary) in ready_product[1]
I get the message
f1.write(temporary) in ready_product[1]
TypeError: 'in <string>' requires string as left operand, not int
When i do print(type()) in temporary it says string. I also tried str(quantity_of_product), but it doesn't work as well. Maybe somebody could give me the idea of what to do, or what to read to get the answer.

The error is arising because you are asking python to find out whether an integer is "in" a string.
The output of f1.write(temporary) is an integer. To see this, try adding a print statement before the erroneous line. In contrast, ready_product[1] is a string (i.e. the second string element in the list "ready_product").
The operator "in" takes two iterables and returns whether the first is "in" the second. For example:
>>> "hello in ["hello", "world"]
>> True
>>> "b" in "a string"
>> False
When Python attempts to see if an integer is "in" a string, it cannot and throws a TypeError, saying "requires string as left operand, not int". This is the root of your error.
You may also have a number of other errors in your code:
"list" is a reserved word in Python, and so calling your variable "list" is bad practice. Try another name such as _list (or delete the variable as it doesn't appear to serve a purpose).
"del line" deletes the variable "line". However, it won't delete the actual line in the text file, only the variable containing it. See Deleting a specific line in a file (python) for how to delete a line from a text file.
There doesn't appear to be a f1.close() statement in the code. This is necessary to close the file after use, as otherwise edits may not be saved.
Personally, instead of attempting to delete lines as I go, I'd maintain a list of lines in the text file, and delete/alter lines from the list as I go. Then, at the end of the program I'd rewrite the file from the list of altered lines.

Related

Python variables stored in text files not working, but should be

I've settled on a text-file based save system for my game, storing the values of required variables with keywords - for example, the password that tells the game which chapter to play. However, it appears to be malfunctioning, and I can't see why.
Before starting the game, we have:
if not os.file.isfile('TSGsave{0}.txt'.format(name)):
TSGsave=open('TSGsave{0}.txt'.format(name),'wt')
TSGsave.write('\nw5CT$n<jfW=-#J%4Ya5##')
TSGsave.close()
(the keyword used is a bunch of jibberish so that the user can't change it knowing what's going to happen). This adds w5CT$n<jfW=-#J%4Ya5## to the text file. We then have:
for i in range (len(lines)):
if 'w5CT$n<jfW' in lines[i]:
findpass=lines[i]
for i in range (len(findpass)):
if findpass[i]=='=':
cutfrom=i+1
password=findpass[cutfrom:len(findpass)]
to retrieve the variable (which can change, so it can't be written in as definite value). I know it works, because I added print (password) to the code and it returned -#J%4Ya5##. Then to start the corresponding chapter, the code is:
if password=='-#J%4Ya5##':
but it isn't starting the indented block. In the shell, the program ends and goes back to the >>> line.
If there is a way to fix this code, great - but another code to do the same thing would work just as well.
Your lines contain newlines, and these are being included. Strip these from the line:
findpass = lines[i].rstrip('\n')
Printing a value with a newline in it will simply add an extra black line after the print. Always use the repr() function to produce a Python representation of strings to see such characters:
>>> print '-#J%4Ya5##\n'
-#J%4Ya5##
>>> print repr('-#J%4Ya5##\n')
'-#J%4Ya5##\n'
Your parsing code is overly complicated; you can use str.split() or str.partition() to split your password from the line instead. You should just loop over the lines list directly rather than produce indices with range():
for line in lines:
if 'w5CT$n<jfW' in line:
password = line.partition('=')[2].rstrip('\n')

basic python file IO homework

I'm having trouble figuring out where I'm going wrong here.
The original file is:
python is a programming language that lets you WORK more quickly and integrate your systems more effectively.
you can learn to use python and see almost immediate gains in PRODUCTIVITY and lower maintenance COSTS.
it's very helpful for any field of study.
I'm trying to create a function that takes a file and reads it and then capitalizes the sentences, changes the caps lock to lower case and the "it's" to "this is". Then put the file back together and add a period after the sentences. Write the new file string into a .txt file named 'Edited.txt.
My code is:
def edit(aFile):
f = open(aFile, 'r')
xs = f.readlines()
f.close()
g = open('happy.txt', 'w')
for x in xs:
x.capitalize()
if x.isupper==1:
x.lower()
g.write(x)
g.close()
The error I get is "File not found-happy.txt(Access is denied). I tried to read the file and couldn't.
I am 100% positive that the file is there and the media path is set to the folder.
isupper
is a method that returns True or False, so the line should read:
if x.isupper():
not
if x.isupper==1:
Not sure if this answers your question, but you should really post more about the error for us to answer properly.
Additionally, many of the python string methods, such as capitalize() and lower() create COPIES of the string, and don't actually modify the original string. So if:
x = "TEST"
then calling
y = x.lower()
will result in x still being "TEST" and y being "test".
This statement doesn't do anything as is:
x.capitalize()
It returns x with the first character capitalized, but you don't save the results anywhere. Also, x remains unchanged after this statement. If you want to capitalize the first char of x, do this:
x = x.capitalize()
The first major mistake that I can see is that you are doing string methods without assigning them to anything. Strings are immutable, so x.capitalize() does nothing (as jh314 said).
In addition to what the others have said, your for x in xs line is saying "for every line in the file, do the following". Your file appears to only be one line, so you are trying to do everything on one line.
Try looking at the documentation on regular expressions and string methods.
http://docs.python.org/2/library/string.html
http://docs.python.org/2/library/re.html
They should be helpful for identifying the places within your line that you would like to modify.

more ids getting deleted from resulting text file

I have an id in invalid_change variable which I am trying to delete from the input file "list.txt" and create a file results.txt as below..can anyone provide inputs on how can this be fixed?I have a sample input and expected output below..
'''
INPUT(list.txt:-
350882 348521 350166
346917 352470
360049
EXPECTEDOUTPUT(results.txt):-
350882 348521 350166
346917
360049
'''
invalid_list=['352470','12345']
f_write = open('results.txt', 'wb')
with open('list.txt','r') as f :
for line in f :
#delete the whole line if any invalid gerrit is presnet
gerrit_list = line.strip().split(' ')
ifvalid = True
for gerrit in gerrit_list:
try: # check if invalid gerrit is present
invalid_gerrit.index(invalid_change)
ifvalid = False
break
except:
pass
if ifvalid:
f_write.write(line)
f_write.close()
The problem is that when you reach this line:
346917 352470
the ifvalid variable is set to False and thus this specific line (even if adjusted) is not being written to the output file.
Possible solutions:
Modify string eg. using regular expressions. They will do replacing.
Do not skip writing "invalid" line to a file, just prepare it without the ID you want to remove (as in solution no. 1).
Let us know, if you have any questions.
Other problems in your code are:
diaper anti-pattern (you catch all the exceptions, including NameError, while you should only catch ValueError, or rather performing test including in keyword) - this is the reason you do not see errors related to lack of invalid_change and invalid_gerrit variables,
instead of opening and closing f_write, you could use it also in with statement you are already using, if you have Python 2.7+ or 3.1+,
str.split() splits by default by whitespaces, and removes empty strings from result, so instead of writing line.strip().split(' ') you could just write line.split(),
Each item in gerrit_list is an individual number. You don't need to find whether the invalid change is contained within the number. In fact, that can cause bugs. You can just directly iterate through the items in gerrit_list and throw away the ones that match invalid_list:
for line in f:
gerrit_list = line.split()
valid_gerrits = [gerrit for gerrit in gerrit_list if gerrit not in invalid_list]
if valid_gerrits:
newline = ' '.join(valid_gerrits) + '\n'
f_write.write(newline)

python read output

Write a program that outputs the first number within a file specified by the user. It should behave like:
Enter a file name: l11-1.txt
The first number is 20.
You will need to use the file object method .read(1) to read 1 character at a time, and a string object method to check if it is a number. If there is no number, the expected behaviour is:
Enter a file name: l11-2.txt
There is no number in l11-2.txt.
Why is reading 1 character at a time a better algorithm than calling .read() once and then processing the resulting string using a loop?
I have the files and it does correspond to the answers above but im not sure how to make it output properly.
The code i have so far is below:
filenm = raw_input("Enter a file name: ")
datain=file(filenm,"r")
try:
c=datain.read(1)
result = []
while int(c) >= 0:
result.append(c)
c = datain.read(1)
except:
pass
if len(result) > 0:
print "The first number is",(" ".join(result))+" . "
else:
print "There is no number in" , filenm + "."
so far this opens the file and reads it but the output is always no number even if there is one. Can anyone help me ?
OK, you've been given some instructions:
read a string input from the user
open the file given by that string
.read(1) a character at a time until you get the first number or EOF
print the number
You've got the first and second parts here (although you should use open instead of file to open a file), what next? The first thing to do is to work out your algorithm: what do you want the computer to do?
Your last line starts looping over the lines in the file, which sounds like not what your teacher wants -- they want you to read a single character. File objects have a .read() method that lets you specify how many bytes to read, so:
c = datain.read(1)
will read a single character into a string. You can then call .isdigit() on that to determine if it's a digit or not:
c.isdigit()
It sounds like you're supposed to keep reading a digit until you run out, and then concatenate them all together; if the first thing you read isn't a digit (c.isdigit() is False) you should just error out
Your datain variable is a file object. Use its .read(1) method to read 1 character at a time. Take a look at the string methods and find one that will tell you if a string is a number.
Why is reading 1 character at a time a better algorithm than calling .read() once and then processing the resulting string using a loop?
Define "better".
In this case, it's "better" because it makes you think.
In some cases, it's "better" because it can save reading an entire line when reading the first few bytes is enough.
In some cases, it's "better" because the entire line may not be sitting around in the input buffer.
You could use regex like (searching for an integer or a float):
import re
with open(filename, 'r') as fd:
match = re.match('([-]?\d+(\.\d+|))', fd.read())
if match:
print 'My first number is', match.groups()[0]
This with with anything like: "Hello 111." => will output 111.

Problem with Boolean Expression with a string value from a lIst

I have the following problem:
# line is a line from a file that contains ["baa","beee","0"]
line = TcsLine.split(",")
NumPFCs = eval(line[2])
if NumPFCs==0:
print line
I want to print all the lines from the file if the second position of the list has a value == 0.
I print the lines but after that the following happens:
Traceback (most recent call last):
['baaa', 'beee', '0', '\n']
BUT after I have the next ERROR
ilation.py", line 141, in ?
getZeroPFcs()
ilation.py", line 110, in getZeroPFcs
NumPFCs = eval(line[2])
File "<string>", line 0
Can you please help me?
thanks
What0s
Let me explain a little what you do here.
If you write:
NumPFCs = eval(line[2])
the order of evaluation is:
take the second character of the string line, i.e. a quote '"'
eval this quote as a python expression, which is an error.
If you write it instead as:
NumPFCs = eval(line)[2]
then the order of evaluation is:
eval the line, producing a python list
take the second element of that list, which is a one-character string: "0"
a string cannot be compared with a number; this is an error too.
In your terms, you want to do the following:
NumPFCs = eval(eval(line)[2])
or, slightly better, compare NumPFCs to a string:
if NumPFCs == "0":
but the ways this could go wrong are almost innumerable. You should forget about eval and try to use other methods: string splitting, regular expressions etc. Others have already provided some suggestions, and I'm sure more will follow.
Your question is kind of hard to read, but using eval there is definitely not a good idea. Either just do a direct string comparison:
line=TcsLine.split(",")
if line[2] == "0":
print line
or use int
line=TcsLine.split(",")
if int(line[2]) == 0:
print line
Either way, your bad data will fail you.
I'd also recomment reading PEP 8.
There are a few issues I see in your code segment:
you make an assumption that list always has at least 3 elements
eval will raise exception if containing string isn't valid python
you say you want second element, but you access the 3rd element.
This is a safer way to do this
line=TcsLine.split(",")
if len(line) >=3 and line[2].rfind("0") != -1:
print line
I'd recommend using a regular expression to capture all of the variants of how 0 can be specified: with double-quotes, without any quotes, with single quotes, with extra whitespace outside the quotes, with whitespace inside the quotes, how you want the square brackets handled, etc.
There are many ways of skinning a cat, as it were :)
Before we begin though, don't use eval on strings that are not yours so if the string has ever left your program; i.e. it has stayed in a file, sent over a network, someone can send in something nasty. And if someone can, you can be sure someone will.
And you might want to look over your data format. Putting strings like ["baa","beee","0", "\n"] in a file does not make much sense to me.
The first and simplest way would be to just strip away the stuff you don't need and to a string comparison. This would work as long as the '0'-string always looks the same and you're not really after the integer value 0, only the character pattern:
TcsLine = '["baa","beee","0"]'
line = TcsLine.strip('[]').split(",")
if line[2] == '"0"':
print line
The second way would be to similar to the first except that we cast the numeric string to an integer, yielding the integer value you were looking for (but printing 'line' without all the quotation marks):
TcsLine = '["baa","beee","0"]'
line = [e.strip('"') for e in TcsLine.strip('[]').split(",")]
NumPFCs = int(line[2])
if NumPFCs==0:
print line
Could it be that the string is actually a json array? Then I would probably go get simplejson to parse it properly if I were running Python<2.6 or just import json on Python>=2.6. Then cast the resulting '0'-string to an integer as in the previous example.
TcsLine = '["baa","beee","0"]'
#import json # for >= Python2.6
import simplejson as json # for <Python2.6
line = json.loads(TcsLine)
NumPFCs = int(line[2])
if NumPFCs==0:
print line

Categories