def main():
try:
with open("actions.txt", "r") as infile:
line = infile.readlines()
except FileNotFoundError:
exit(f"tried to open file {actions.txt}, file not fount")
a = 20
aN = 0
Set = set()
while line != "":
line_1 = line.rstrip("\n")
line_1 = line_1.rsplit(", ")
print(line_1)
if a != 0:
if line_1[2] == "a" and int(line_1[3]) <= a and aN <= 2:
aN += 1
a = a - int(line_1[3])
Set.add(f"a's: {line_1[0]} {line_1[3]} ,")
print(Set)
The main idea of this code is to read a txt file containing information about a variable a, if it's found in the code, then it does some operation with that variable and outputs itself.
my code worked w/o an introduction of a "main" function. But i have to read the file using a def main(). I have no output as the file can't be read due to the improper referencing of variable. Hope for ur help
Related
I want to delete a line of text from a .txt file given an integer corresponding to the txt file's line number. For example, given the integer 2, delete line 2 of the text file.
I'm sort of lost on what to put into my program.
f = open('text1.txt','r+')
g = open('text2.txt',"w")
line_num = 0
search_phrase = "Test"
for line in f.readlines():
line_num += 1
if line.find(search_phrase) >= 0:
print("text found a line" , line_num)
decision = input("enter letter corresponding to a decision: (d = delete lines, s = save to new txt) \n")
if decision == 'd':
//delete the current line
if decision == 's':
//save the current line to a new file
Any help is appreciated! Thanks :)
This way:
with open('text1.txt','r') as f, open('text2.txt',"w") as g:
to_delete=[2,4]
for line_number, line in enumerate(f.readlines(), 1):
if line_number not in to_delete:
g.write(line)
else:
print(f'line {line_number}, "{line.rstrip()}" deleted')
Here it goes.
f = open('data/test.txt','rb')
text = f.readlines() # all lines are read into a list and you can acess it as a list
deleted_line = text.pop(1) #line is deleted and stored into the variable
print(text)
print(deleted_line)
f.write(text) # here you save it with the new data, you can always delete the data in the file to replace by the new one
I am writing a code in python where I am removing all the text after a specific word but in output lines are missing. I have a text file in unicode which have 3 lines:
my name is test1
my name is
my name is test 2
What I want is to remove text after word "test" so I could get the output as below
my name is test
my name is
my name is test
I have written a code but it does the task but also removes the second line "my name is"
My code is below
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index > 0:
txt += line[:index + len(splitStr)] + "\n"
with open(r"test.txt", "w") as fp:
fp.write(txt)
It looks like if there is no keyword found the index become -1.
So you are avoiding the lines w/o keyword.
I would modify your if by adding the condition as follows:
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index > 0:
txt += line[:index + len(splitStr)] + "\n"
elif index < 0:
txt += line
with open(r"test.txt", "w") as fp:
fp.write(txt)
No need to add \n because the line already contains it.
Your code does not append the line if the splitStr is not defined.
txt = ""
with open(r"test.txt", 'r') as fp:
for line in fp.readlines():
splitStr = "test"
index = line.find(splitStr)
if index != -1:
txt += line[:index + len(splitStr)] + "\n"
else:
txt += line
with open(r"test.txt", "w") as fp:
fp.write(txt)
In my solution I simulate the input file via io.StringIO. Compared to your code my solution remove the else branch and only use one += operater. Also splitStr is set only one time and not on each iteration. This makes the code more clear and reduces possible errore sources.
import io
# simulates a file for this example
the_file = io.StringIO("""my name is test1
my name is
my name is test 2""")
txt = ""
splitStr = "test"
with the_file as fp:
# each line
for line in fp.readlines():
# cut somoething?
if splitStr in line:
# find index
index = line.find(splitStr)
# cut after 'splitStr' and add newline
line = line[:index + len(splitStr)] + "\n"
# append line to output
txt += line
print(txt)
When handling with files in Python 3 it is recommended to use pathlib for that like this.
import pathlib
file_path = pathlib.Path("test.txt")
# read from wile
with file_path.open('r') as fp:
# do something
# write back to the file
with file_path.open('w') as fp:
# do something
Suggestion:
for line in fp.readlines():
i = line.find('test')
if i != -1:
line = line[:i]
This problem only occurs when I include the print line I commented out below.
fname = input("Enter file name: ")
if len(fname) < 1:
fname = "mbox-short.txt"
fh = open(fname)
i = 0
count = 0
with open(fname, 'r') as fh:
for line in fh:
temp = line.split()
#print(temp[0])
count+=1
print(count)
When you attempt to split an empty string it returns an empty list:
>>> ''.split()
[]
For this reason, attempting to access temp[0] throws an IndexError exception and your processing stops. You could fix it like so:
if not line: # line is blank
continue
When a line is empty, temp is also empty. There is no temp[0] to print, and Python terminates with an uncaught IndexError.
Say customPassFile.txt has two lines in it. First line is "123testing" and the second line is "testing321". If passwordCracking = "123testing", then the output would be that "123testing" was not found in the file (or something similar). If passwordCracking = "testing321", then the output would be that "testing321" was found in the file. I think that the for loop I have is only reading the last line of the text file. Any solutions to fix this?
import time
import linecache
def solution_one(passwordCracking):
print("Running Solution #1 # " + time.strftime("%Y-%m-%d %H:%M:%S",time.localtime()))
startingTimeSeconds = time.time()
currentLine = 1
attempt = 1
passwordFound = False
wordListFile = open("customPassFile.txt", encoding="utf8")
num_lines = sum(1 for line in open('customPassFile.txt'))
while(passwordFound == False):
for i, line in enumerate(wordListFile):
if(i == currentLine):
line = line
passwordChecking = line
if(passwordChecking == passwordCracking):
passwordFound = True
endingTimeSeconds = time.time()
overallTimeSeconds = endingTimeSeconds - startingTimeSeconds
print("~~~~~~~~~~~~~~~~~")
print("Password Found: {}".format(passwordChecking))
print("ATTEMPTS: {}".format(attempt))
print("TIME TO FIND: {} seconds".format(overallTimeSeconds))
wordListFile.close()
break
elif(currentLine == num_lines):
print("~~~~~~~~~~~~~~~~~")
print("Stopping Solution #1 # " + time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
print("REASON: Password could not be cracked")
print("ATTEMPTS: {}".format(attempt))
break
else:
attempt = attempt + 1
currentLine = currentLine + 1
continue
The main problem with your code is that you open the file and you read it multiple times. The first time the file object position goes to the end and stays there. Next time you read the file nothing happens, since you are already at the end of the file.
Example
Sometimes an example is worth more than lots of words.
Take the file test_file.txt with the following lines:
line1
line2
Now open the file and read it twice:
f = open('./test_file.txt')
f.tell()
>>> 0
for l in f:
print(l, end='')
else:
print('nothing')
>>> line1
>>> line2
>>> nothing
f.tell()
>>> 12
for l in f:
print(l, end='')
else:
print('nothing')
>>> nothing
f.close()
The second time nothing happen, as the file object is already at the end.
Solution
Here you have two options:
you read the file only once and save all the lines in a list and then use the list in your code. It should be enough to replace
wordListFile = open("customPassFile.txt", encoding="utf8")
num_lines = sum(1 for line in open('customPassFile.txt'))
with
with open("customPassFile.txt", encoding="utf8") as f:
wordListFile = f.readlines()
num_lines = len(wordListFile)
you reset the file object position after you read the file using seek. It would be something along the line:
for i, line in enumerate(wordListFile):
if(i == currentLine):
line = line
wordListFile.seek(0)
I would go with option 1., unless you have memory constraint (e.g. the file is bigger than memory)
Notes
I have a few extra notes:
python starts counters with 0 (like c/c++) and not 1 (like fortran). So probably you want to set:
currentLine = 0
when you read a file, the new line character \n is not stripped, so you have to do it (with strip) or account for it when comparing strings (using e.g. startswith). As example:
passwordChecking == passwordCracking
will likely always return False as passwordChecking contains \n and passwordCracking very likely doesn't.
Disclamer
I haven't tried the code, nor my suggestions, so there might be other bugs lurking around.
**I will delete this answer after OP understands the problem in indentation of I understand his intention of his code.*
for i, line in enumerate(wordListFile):
if(i == currentLine):
line = line
passwordChecking = line
#rest of the code.
Here your code is outside of for loop so only last line is cached.
for i, line in enumerate(wordListFile):
if(i == currentLine):
line = line
passwordChecking = line
#rest of the code.
Am writing a program that opens a file and looks for line which are like this:
X-DSPAM-Confidence: 0.8475.
I want to use the split and find function to extract these lines and put it in a variable. This is the code I have written:
fname = raw_input("Enter file name: ")
if len(fname) == 0:
fname = 'mbox-short.txt'
fh = open(fname,'r')
total = 0
for line in fh:
if not line.startswith("X-DSPAM-Confidence:"): continue
Please, Please I am now beginning in python so please give me something simple which I can understand to help me later on. Please, Please.
I think the only wrong part is not in if :
fname = raw_input("Enter file name: ")
if len(fname) == 0:
fname = 'mbox-short.txt'
fh = open(fname,'r')
total = 0
lines = []
for line in fh:
if line.startswith("X-DSPAM-Confidence:"):
lines.append(line)
First receive the input with raw_input()
fname = raw_input("Enter file name: ")
Then check if the input string is empty:
if not fname:
fname = 'mbox-short.txt'
Then, open the file and read it line by line:
lines = []
with open(fname, 'r') as f:
for line in f.readlines():
if line.startswith("X-DSPAM-Confidence:"):
lines.append(line)
The with open() as file statement just ensures that the file object gets closed when you don't need it anymore. (file.close() is called automatically upon exiting out of the with clause)
I know where this one is coming from as I've done it myself some time ago. As far as I remember you need to calculate the average :)
fname = raw_input("Enter file name: ")
fh = open(fname)
count = 0
sum = 0
for line in fh:
if not line.startswith("X-DSPAM-Confidence:") : continue
count = count + 1
pos = line.find(' ')
sum = sum + float(line[pos:])
average = sum/count
You're very close, you just need to add a statement below the continue adding the line to a list.
fname = raw_input("Enter file name: ")
if len(fname) == 0:
fname = 'mbox-short.txt'
fh = open(fname,'r')
total = 0
lines = []
for line in fh:
if not line.startswith("X-DSPAM-Confidence:"):
continue
lines.append(line) # will only execute if the continue is not executed
fh.close()
You should also look at the with keyword for opening files - it's much safer and easier. You would use it like this (I also swapped the logic of your if - saves you a line and a needless continue):
fname = raw_input("Enter file name: ")
if len(fname) == 0:
fname = 'mbox-short.txt'
total = 0
good_lines = []
with open(fname,'r') as fh:
for line in fh:
if line.startswith("X-DSPAM-Confidence:"):
good_lines.append(line)
If you just want the values, you can do a list comprehension with the good_lines list like this:
values = [ l.split()[1] for l in good_lines ]