I'm working on an assignment for school where I have a text file: data.txt which looks like this:(instead of 'name' there are actual names I just replaced them here)
10001-31021 'name' 2015.12.30. 524432
10001-31121 'name' 2016.03.21. 765432
10012-34321 'name' 2016.02.20. 231231
10201-11021 'name' 2016.01.10. 2310456
And I have an update.txt which looks like this:
2016.03.22.
10001-31021 'name' +20000
10012-34321 'name' +35432
10012-34321 'name' -10000
10120-00123 'name' +120334
10001-31021 'name' +5000
10210-41011 'name' -6000
10201-11021 'name' +100210
12345-32100 'name' +123456
And I have to make a newdata.txt file according to the changes to the last column that update.txt includes.
This is my code so far:
adat = open("data.txt", "r")
newdata = open("newdata.txt", "w")
update = open("update", "r")
date = update.readline().decode("utf-8-sig").encode("utf-8").splitlines()
num_lines = sum(1 for line in open('update'))
elsociklus = 0
masodikciklus = 0
for num_lines in update:
updateData = re.search("(.{11}\t)(\D+\t)([+-]\d+)", num_lines)
elsociklus = elsociklus + 1
print("elsociklus: " + str(elsociklus))
for j in adat:
data = re.search("(.{11}\t)(\D+\t)(\d{4}\.\d{2}\.\d{2}\.\t)(\d+)", j)
masodikciklus = masodikciklus + 1
print("masodikciklus: " + str(masodikciklus))
if data != None:
if updateData.group(1) == data.group(1):
print("regi: " + data.group(0))
print("update: " + updateData.group(0))
print("uj: " + data.group(1) + data.group(2) + date[0] + "\t" + str(int(data.group(4)) + int(updateData.group(3))))
newdata.write(data.group(1) + data.group(2) + date[0] + "\t" + str(int(data.group(4)) + int(updateData.group(3))))
newdata.write("\n")
else:
print("nincs valtozas: " + data.group(0))
adat.close()
newdata.close()
update.close()
My problem is with the nested loop. I just can't figure it out why it isn't entering the inner loop for the second time. It works perfectly on the first iteration but when entering the 2nd one in the outer loop it just ignores the inner loop.
Thank you in advance for your help.
Thanks to codingCat for the answer. I fixed the problem by returning my file pointer to the beginning of my file in the inner loop
Related
I have the following code:
for line in contents:
line_fields = line.strip().split()
f2.write("ID: " + line_fields[0] + '\n')
f2.write("Name:" + line_fields[1] + '\n')
What I am trying to do is write ID only once for each number contained in line_fields[0]. So, it should look like the left instead of the right column:
ID: 1 ID: 1
Name1 Name1
Name1 ID: 1
ID: 2 Name1
Name2 ID: 2
Name2 Name2
...
I am actually quite confused and would be very grateful to get some advice from you
If you dont want to deal with dicts you can do this:
current = ""
for line in contents:
line_fields = line.strip().split()
if current != line_fields[0]:
f2.write("ID: " + line_fields[0] + '\n')
current = line_fields[0]
f2.write("Name:" + line_fields[1] + '\n')
It will only write ID if it is different from the previous one.
Thanks for asking the question.
You can use dictionary as check mechanism to view the repeated values.
As pointed out by author
d = {}
for line in contents:
line_fields = line.strip().split()
if line_fields[0] not in d.keys():
f2.write("ID: " + line_fields[0] + '\n')
f2.write("Name:" + line_fields[0] + '\n')
d[line_fields[0]] = line_fields[1]
I’m writing a program that makes music albums into files that you can search for, and for that i need a str in the file that have a specific value that is made after the list is complete. Can you go back in that list and change a blank str with a new value?
I have searched online and found something called words.replace, but it doesn’t work, i get a Attribute error.
def create_album():
global idnumber, current_information
file_information = []
if current_information[0] != 'N/A':
save()
file_information.append(idnumber)
idnumber += 1
print('Type c at any point to abort creation')
for i in creation_list:
value = input('\t' + i)
if value.upper == 'C':
menu()
else:
-1file_information.append('')
file_information.append(value)
file_information.append('Album created - ' + file_information[2] +'\nSongs:')
-2file_information = [w.replace(file_information[1], str(file_information[0]) + '-' + file_information[2]) for w in file_information]
current_information = file_information
save_name = open(save_path + str(file_information[0]) + '-' + str(file_information[2]) + '.txt', 'w')
for i in file_information:
save_name.write(str(i) + '\n')
current_files_ = open(information_file + 'files.txt', 'w')
filenames.append(file_information[0])
for i in filenames:
current_files_.write(str(i) + '\n')
id_file = open(information_file + 'albumid.txt', 'w')
id_file.write(str(idnumber))
-1 is where i have put aside a blank row
-2 is the where i try to replace row 1 in the list with the value of row 0 and row 2.
The error message I receive is ‘int’ object has no attribute ‘replace’
Did you try this?
-2file_information = [w.replace(str(file_information[1]), str(file_information[0]) + '-' + file_information[2]) for w in file_information]
I'm having trouble with a loop writing to a text file. I'm trying to create a tab delimited text file that writes an ID, date, time, sequence number, and text from a transcript to a line, then starts a new line every time it reaches bold text.
When there is only 1 ID in my company_list, everything works great and it produces this example below:
However, as soon as I add an additional ID to the company_list, it produces this:
It looks like when a second company ID is added, that a new line is placed after every ID for some unknown reason. What's even weirder is that when the loop runs the last company ID in the list, that data is formatted correctly. There are no errors produced at all. If anyone has any idea what is going on here I would really appreciate it.
Code snippet below:
company_list = open('Company_List.txt')
for line in company_list:
company_id = WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.XPATH, "//*[#id='SearchTopBar']")))
company_id.send_keys(line + Keys.ENTER)
driver.implicitly_wait(10)
driver.find_element_by_link_text("Transcripts").click()
driver.implicitly_wait(10)
driver.find_element_by_partial_link_text("Q1 2018").click()
date = driver.find_element_by_xpath('//*[#id="ctl01__header__dateLabel"]').text
struct_time = time.strptime(date, "%A, %B %d, %Y %I:%M %p")
speaker = 1
p_tag = driver.find_elements_by_tag_name('p')
file = open("q1_2018.txt", "a", encoding='utf-8-sig')
for i in range(3,len(p_tag) - 6):
element = driver.find_element_by_xpath('//*[#id="ctl01__bodyRow"]/td/p[' + str(i) + ']')
weight = int(element.value_of_css_property('font-weight'))
if weight == 700:
file.write('\n' + line + '\t' + str(struct_time[0]) + str(struct_time[1]) + str(struct_time[2]) + '\t' + str(struct_time[3]) + str(struct_time[4]) + '\t' + str(speaker) + '\t')
file.write(driver.find_element_by_xpath('//*[#id="ctl01__bodyRow"]/td/p[' + str(i + 1) + ']').text + ' ')
speaker = speaker + 1
else:
file.write(driver.find_element_by_xpath('//*[#id="ctl01__bodyRow"]/td/p[' + str(i) + ']').text + ' ')
file.close()
Brand new to programming but very enjoyable challenge.
Here's a question which I suspect may be caused by a misunderstanding of python loops.
System info: Using notepad++ and IDLE python 3.4.3 on Win 7 32-bit
My solution is to open 1 database, use it to look for a correct master entry from database 2, pulls a index number (task_no), then write a 3rd file identical to the first database, this time with the correct index number.
My problem is that it performs 1st and 2nd loop correctly, then on the 2nd iteration of loop 1, tries to perform a block in loop 2 while iterating through the rows of loop 1, not the task_rows of loop 2.
footnote: Both files are quite large (several MB) so I'm note sure if storing them in memory is a good idea.
This was a relevant question that I found closest to this problem:
python nested loop using loops and files
What I got out of it was that I tried moving the file opening within the 1st loop, but the problem persists. Something to do with how I'm using CSV reader?
I also have the sinking suspicion that there may be a root cause in problem solving so I am welcome to suggestions for alternative ways to solve the problem.
Thanks in advance!
The gist:
for row in readerCurrentFile: #LOOP 1
# iterates through readerCurrentFile to define search variables
[...]
for task_row in readerTaskHeader: #LOOP 2
# searches each row iteratively through readerTaskHeader
# Match compid
#if no match, continue <<<- This is where it goes back to 1st loop
[...]
# Match task frequency
#if no match, continue
[...]
# once both of the above matches check out, will grab data (task_no from task_row[0]
task_no = ""
task_no = task_row[0]
if task_row:
break
[...]
# writes PM code
print("Successful write of PM schedule row")
print(compid + " " + dict_freq_names[str(pmfreqx) + str(pmfreq)] + ": " + pmid + " " + task_no)
The entire code:
import csv
import re
#Writes schedule
csvNewPMSchedule = open('new_pm_schedule.csv', 'a', newline='')
writerNewPMSchedule = csv.writer(csvNewPMSchedule)
# Dictionaries of PM Frequency
def re_compile_dict(d,f):
for k in d:
d[k] = re.compile(d[k], flags=f)
dict_month = {60:'Quin',36:'Trien',24:'Bi-An',12:'Annual(?<!Bi-)(?<!Semi-)',6:'Semi-An',3:'Quart',2:'Bi-Month',1:'Month(?<!Bi-)'}
dict_week = {2:'Bi-Week',1:'Week(?<!Bi-)'}
dict_freq_names = {'60Months':'Quintennial','36Months':'Triennial','24Months':'Bi-Annual','12Months':'Annual','6Months':'Semi-Annual','3Months':'Quarterly','2Months':'Bi-Monthly','1Months':'Monthly','2Weeks':'Bi-Weekly','1Weeks':'Weekly'}
re_compile_dict(dict_month,re.IGNORECASE)
re_compile_dict(dict_week, re.IGNORECASE)
# Unique Task Counter
task_num = 0
total_lines = 0
#Error catcher
error_in_row = []
#Blank out all rows
pmid = 0
compid = 0
comp_desc = 0
pmfreqx = 0
pmfreq = 0
pmfreqtype = 0
# PM Schedule Draft (as provided by eMaint)
currentFile = open('pm_schedule.csv', encoding='windows-1252')
readerCurrentFile = csv.reader(currentFile)
# Loop 1
for row in readerCurrentFile:
if row[0] == "pmid":
continue
#defines row items
pmid = row[0]
compid = row[1]
comp_desc = row[2]
#quantity of pm frequency
pmfreqx_temp = row[3]
#unit of pm frequency, choices are: Months, Weeks
pmfreq = row[4]
#pmfreqtype is currently only static not sure what other options we have
pmfreqtype = row[5]
#pmnextdate is the next scheduled due date from this one. we probably need logic later that closes out any past due date
pmnextdate = row[6]
# Task Number This is what we want to change
# pass
# We want to change this to task header's task_desc
sched_task_desc = row[8]
#last done date
last_pm_date = row[9]
#
#determines frequency search criteria
#
try:
pmfreqx = int(pmfreqx_temp)
except (TypeError, ValueError):
print("Invalid PM frequency data, Skipping row " + pmid)
error_in_row.append(pmid)
continue
#
#defines frequency search variable
#
freq_search_var = ""
if pmfreq == "Weeks":
freq_search_var = dict_week[pmfreqx]
elif pmfreq == "Months":
freq_search_var = dict_month[pmfreqx]
if not freq_search_var:
print("Error in assigning frequency" + compid + " " + str(pmfreqx) + " " + pmfreq)
error_in_row.append(pmid)
continue
#defines Equipment ID Search Variable
print(compid + " frequency found: " + str(pmfreqx) + " " + str(pmfreq))
compid_search_var = re.compile(compid,re.IGNORECASE)
#
# Matching function - search taskHeader for data
#
#PM Task Header Reference
taskHeader = open('taskheader.csv', encoding='windows-1252')
readerTaskHeader = csv.reader(taskHeader)
for task_row in readerTaskHeader:
# task_row[0]: taskHeader pm number
# task_row[1]: "taskHeader task_desc
# task_row[2]: taskHeader_task_notes
#
# search for compid
compid_match = ""
compid_match = compid_search_var.search(task_row[1])
if not compid_match:
print(task_row[1] + " does not match ID for " + compid + ", trying next row.") #debug 2
continue # <<< STOPS ITERATING RIGHT OVER HERE
print("Found compid " + task_row[1]) # debug line
#
freq_match = ""
freq_match = freq_search_var.search(task_row[1])
if not freq_match:
print(task_row[1] + " does not match freq for " + compid + " " + dict_freq_names[str(pmfreqx) + str(pmfreq)] + ", trying next row.") #debug line
continue
print("Frequency Match: " + compid + " " + dict_freq_names[str(pmfreqx) + str(pmfreq)]) # freq debug line
#
task_no = ""
print("Assigning Task Number to " + task_row[0])
task_no = task_row[0]
if task_row:
break
#
#error check
#
if not task_no:
print("ERROR IN SEARCH " + compid + " " + pmid)
error_in_row.append(pmid)
continue
#
# Writes Rows
#
writerNewPMSchedule.writerow([pmid,compid,comp_desc,pmfreqx,pmfreq,pmfreqtype,pmnextdate,task_no,sched_task_desc,last_pm_date])
print("Successful write of PM schedule row")
print(compid + " " + dict_freq_names[str(pmfreqx) + str(pmfreq)] + ": " + pmid + " " + task_no)
print("==============")
# Error reporting lined out for now
# for row in error_in_row:
# writerNewPMSchedule.writerow(["Error in row:",str(error_in_row[row])])
# print("Error in row: " + str(error_in_row[row]))
print("Finished")
I have a text file that I want to parse based on the condition that if I find the match phrase in the line then I have to jump to the next line to fetch the value{unfortunately that's how the reports logs are generated}. I have created _dict to check my key and fetch my values in the next line.
Lines = f1.readlines()
numlines = len(Lines)
f1.close()
f1 = open('Testlog.txt','r')
f2 =open('writetoFile','r+')
f3 =open('Results.txt','w')
new_line="Test Name SubTest passed failed status "
f3.write(new_line)
f3.write("\n")
while i < numlines:
line=f1.readline()
if "Test Name" in line:
f2.write(line)
i=i+1
line =f1.readline()
if "true" in line:
f2.write(line)
line = line.strip('\n ')
#print line
data = re.split(r"\s{2,}",line)
Test_Name=data[4]
SubTest=data[6]
passed=data[7]
failed=data[8]
status=data[9]
result = Test_Name + " " + SubTest + " " + passed + " " + failed + " " + status
print result
f3.write(result)
f3.write("\n")
i=i+1
I was wondering if there better way to do this
What is your method for parsing the line? Can you post sample code, that will help.
To answer your second question, you could make a Dictionary in which each key refers to a List, then you can use a for loop to iterate through each of the values (or whatever you'll need)
foo = { 1 : ['a','b','c'] }
for value in foo[1]:
print(value)
prints a b c