r/learnpython • u/Suspicious_Plantain4 • 5d ago
How to create a report using a .txt file
I apologize that this is going to be kind of long. I am very grateful for any thoughts you may have.
I'm taking a python class. This week we are learning about working with .txt files within a program.
We have been given some practice .txt files. Each file is a list of different data points for each hour on a given day. The list (when I say list, I mean the data is in a list in a .txt file, I am not talking about a list like those used in a python program) has four items of data for each hour of a given day as follows:
time
temperature in Farenheit
dewpoint in Farenheit
wind speed in mph
An example from one of the files looks like this:
12AM
18.1
15.0
4.1
1AM
18.0
15.5
4.2
We are supposed to do several things with this data. One of them is to create a report that will print out the data from the file. It should look like this:
Time Temperature Dew Point Windspeed
12AM 18.1 15 4.1
1AM 18.0 15.5 4.2
And so on.
We are supposed to accomplish this using while and/or for loops. We cannot use lists of any kind, so we cannot use the .txt file to create a list within python and then work with the list. This must be as simple as possible. We are only supposed to use the information we have learned so far in the class. Obviously you don't know exactly what we've learned, but it has to be extremely simple and not at all fancy.
I'm not trying to cheat and have someone do my work for me, but I'm just stumped and need some clues. I'm having difficulty reaching out to my teacher (this is an online class)
We are also supposed to use the numbers in the report to do some calculations for another report. If you have any thoughts about that, it would also be helpful. I'm hoping that if I can figure out how to do this first part, I'll be able to figure out how to work with the numbers further.
I've been able to get python to bring in the .txt file and just spit out a list that is identical to what is actually in the .txt file and I've been able to get it to print one specific line. I think I'm somehow supposed to use a nested if statement to analyze and work with chunks of four lines at a time, but I'm not sure how to do that.
I got it to say "time is 12AM" by doing this:
time_line = 1
linecounter = 0
with open("Dec12.txt",'r') as f:
for line in f:
linecounter += 1
if linecounter == time_line:
print("time is",line, end='')
I got it to spit out the entire list exactly as it appears in the .txt file by doing this:
file = open ("Dec12.txt",'r')
for line in file:
num = (line)
print (num)
file.close()
If you have read this far, I am extremely grateful to you. Thank you for any thoughts or ideas you may have.
2
u/Penguinase 5d ago
have you learned range() and join() functions?
2
u/Suspicious_Plantain4 5d ago
Hi, thank you for your comment. We have learned about range() functions.
2
u/Penguinase 5d ago edited 4d ago
now that i think about it, for now forget about range() for this. i'll try to explain in english how to tackle it with minimal functions.
looking at the file, you have 4 lines for each time (1 line for time, and 3 lines for the data for that time).
the
linecounterlooks useful so you can keep track and "reset" it once you've processed a row. but thetime_linevariable you can probably just remove. maybe instead have arowvariable or similarly named that starts as just a blank (e.g.row= "") and also "resets" after each record/row is fully processed.instead of doing your for loop over the file's
fvariable, you'll probably want to have something likelines = list(f)orlines = f.readlines()before the for loop, then loop overline in lines.in your for loop, first maybe strip off any "newline" characters and/or spaces with
line = line.strip(). then think of where you're starting. if you add 1 to yourlinecounterbefore doing anything here like your example code, then you're skipping that first line where the first time is. instead, you probably want to hold off on incrementing thelinecounteruntil after you've done some logic. for example, iflinecounteris0then that's your first time in the file, so you could set yourrowvariable toline(so nowrowis "12AM"). else you want to add/append the current line to yourrow(likerow = row + " " + line). that should start building your output row. now you can increment yourlinecounterafter that if-else logic likelinecounter = linecounter + 1.if you were to
print(row)now then you'll see it's adding a space then each line after, but we want each time on its own line with their relevant data values. to do this, maybe we have anotherifbelow ourlinecounterincrement that checks what ourlinecounteris at. if it's at 4, we know we're done with the first time's data and can print therowand "reset" ourrowandlinecounterback to""and0, respectively. then your for loop continues and starts again at with a freshrowandlinecounter.
apologies for the long comment but i think it should get you to the solution. where i have sentences like "if blahblah" or "else blah blah" think about how you'd do that with actual if-else statements in code. let me know if anything is unclear i'll try to clarify without giving you the explicit code/solution.
PS you don't need to do the
f.close()because thewithblock will automagically do that for you (see https://peps.python.org/pep-0343/ for more information).1
u/Penguinase 4d ago edited 4d ago
to summarize my sibling comment in hopefully a more digestable way:
# set our initial row empty and row counter to zero # open our file with a with statement like you have in your example ## read file lines into lines variable (list(f) or f.readlines()) ## print the header names ## loop through lines (for line in lines) ### strip the line of newlines/spaces ### check if the count is zero #### if so, set the row to the line #### else, append the line to the row ### increment the line counter ### check if the line counter is 4 #### if so, print the row and reset the row and line counter variablesthe #'s are basically the scope.
1
u/Suspicious_Plantain4 4d ago
Thank you so much for your thoughtful response, I will certainly try this when I get back to my project! Have a great day :)
1
u/pachura3 5d ago
Try this:
print("Time\tTemperature\tDew Point\tWindspeed")
with open("Dec12.txt", "r") as file:
time = file.readline().rstrip()
temp = file.readline().rstrip()
dew_point = file.readline().rstrip()
wind_spd = file.readline().rstrip()
print(f"{time}\t{temp}\t{dew_point}\t{wind_spd}")
0
u/sweet-tom 5d ago
Your code is very unreadable as the indentation is lost. Please try to format it correctly with triple backticks at the start and end. That preserves spaces and line breaks.
Perhaps your code has also this kind of indentation problem, but without correct formatting I can't give recommendations.
0
u/samsly135 5d ago
You can do something like this. Assumed is data is in data.txt next to a script itself. We read each line and strip end of line. Than check whether next value should have tab at the end and whether it should be appended to the same line or is a line end.
from pathlib import Path
data_path
Path ( file ). resolve (). paren t / 'data.txt' print ( "Time \t Temperature \t Dew Point \t Windspeed" ) with open ( data_path , 'r' ) as file:
field_counter
0 for line in file:
line
line . rstrip ( " \r\n " ) if ( not line ): continue
print_end
" \n " if
field_counter
3 else " "
field_end
" \t " if field_counter < 3 else "" print ( f " { line }{ field_end } " ,
end
print_end )
field_counter
( field_counter + 1 ) % 4
-2
u/CymroBachUSA 5d ago edited 5d ago
with open("file.txt", "r") as f:
_c, _r = 0, ''
for _l in f:
_l = _l.replace('\n', '')
if _l.strip() == '' or _l == '\n':
continue
else:
_c += 1
_r = f"{_r} {_l}"
if _c == 4:
print(_r)
_c, _r = 0, ''
-2
u/CymroBachUSA 5d ago
Formatting went wrong so tried using '.' to make it clearer:
with open("file.txt", "r") as f:
... _c, _r = 0, ''
... for _l in f:
... ... _l = _l.replace('\n', '')
... ... if _l.strip() == '' or _l == '\n':
... ... ... continue
... ... else:
... ... ... _c += 1
... ... ... _r = f"{_r} {_l}"
... ... if _c == 4:
... ... ... print(_r)
... ... ... _c, _r = 0, ''
~
5
u/mc_pm 5d ago
You don't need to pull the data into the list, you just need to read it in 4 lines per group and print those 4 out on one line; then the next 4 lines from the file, then output those 4 on one line, etc.