Great. I've changed it to 'while cell_pos.value:' and this works just perfect for my script.
Out of curiosity if I wanted to say go until all the cells E, G, and F are empty, how would I go about that ?
I really appreciate how tolerant you have been and extremely helpful since the past couple of weeks following up on my issues and helping me out with tutorials. Thank you, thank you very much and good luck and best wishes!
will run the "while" loop as long as cell_pos.value is True that is, it is non-empty.
In order to check "all of cells E, G, F are empty" we use the logical operator "and" to combine the three cell values:
1) cell_pos.value
2) cell_alt.value
3) cell_ref.value
Such a condition is called a "compound" condition.
So:
while cell_pos.value and cell_alt.value and cell_ref.value:
will enter the "while" loop as long as all of cells E, G, F are non-empty i.e. they have some value in them. The moment any one of the cells E, G, F is empty, the loop stops.
and
while cell_pos.value or cell_alt.value or cell_ref.value:
will enter the "while" loop as long as any one of cells E, G, F is non-empty. The moment all of cells E, G, F are empty, the loop stops.
Your program will loop through the rows checking only pos value.
So if, in a row, the pos value is non-empty but alt and/or ref values are empty, it will still form the key and try to check if the key exists in the dictionary dict_pos.
This may or may not work, depending on how the dictionary was formed from "scores.txt" text file.
Here's the complete program for your reference:
#!/usr/bin/python
import os
import csv
from openpyxl import load_workbook
from datetime import datetime
from collections import namedtuple
# Variables
sheet_directory = '<absolute_path_till_sheet_directory>'
txt_file = '<absolute_path_till_text_directory>/scores.txt'
def process_xl_sheets():
# Process the text file and form the dictionary of positions
dict_pos = {}
Scores = namedtuple("Scores", ["POS", "ALT", "REF"])
first_line = True
with open(txt_file) as txt_filename:
for line in txt_filename:
if not line.strip(): # Skip empty lines
continue
if first_line: # Skip the header
first_line = False
continue
line = line.rstrip('\n')
x = line.split('\t')
cpos = Scores(POS=x[0], ALT=x[2], REF=x[1])
dict_pos[cpos] = x[3]
# Now process all Excel files
pos_col_no = 'E'
alt_col_no = 'G'
ref_col_no = 'F'
score_col_no = 'V'
row_no = 4
for sheet_root, sheet_dirs, sheet_files in os.walk(sheet_directory):
for sheet_file in sheet_files:
if sheet_file.endswith('.xlsx'):
sheet_xl_file = os.path.join(sheet_root, sheet_file)
wb = load_workbook(sheet_xl_file, data_only=True)
ws = wb.get_sheet_by_name('raw_data')
pos = ws[pos_col_no + str(row_no)].value
alt = ws[alt_col_no + str(row_no)].value
ref = ws[ref_col_no + str(row_no)].value
while pos or alt or ref:
cpos = Scores(POS=str(pos), ALT=alt, REF=ref)
if cpos in dict_pos:
ws[score_col_no + str(row_no)].value = dict_pos[cpos]
else:
ws[score_col_no + str(row_no)].value = 'Unknown_' + datetime.now().strftime("%B") + datetime.now().strftime("%Y")
row_no += 1
pos = ws[pos_col_no + str(row_no)].value
alt = ws[alt_col_no + str(row_no)].value
ref = ws[ref_col_no + str(row_no)].value
wb.save(sheet_xl_file)
# Main section
process_xl_sheets()
Wow! I have not read the entire thread, but the library Pandas is designed for these types of things. You read in the Excel data into a Pandas Dataframe. And you also read in the text file into a Dataframe, both of them is one command each. And then you solve the problem by a few lines of Pandas code, probably you can do that in one line. So your entire solution would be 5-10 lines or so. If you post this question on stack exchange, someone will surely post the entire solution in a few hours.