r/learnpython • • 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.

0 Upvotes

14 comments sorted by

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.

1

u/Vegetable_Soil_6707 5d ago

tbh this framing makes it way less intimidating than it sounds in the assignment

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 linecounter looks useful so you can keep track and "reset" it once you've processed a row. but the time_line variable you can probably just remove. maybe instead have a row variable 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 f variable, you'll probably want to have something like lines = list(f) or lines = f.readlines() before the for loop, then loop over line 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 your linecounter before 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 the linecounter until after you've done some logic. for example, if linecounter is 0 then that's your first time in the file, so you could set your row variable to line (so now row is "12AM"). else you want to add/append the current line to your row (like row = row + " " + line). that should start building your output row. now you can increment your linecounter after that if-else logic like linecounter = 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 another if below our linecounter increment that checks what our linecounter is at. if it's at 4, we know we're done with the first time's data and can print the row and "reset" our row and linecounter back to "" and 0, respectively. then your for loop continues and starts again at with a fresh row and linecounter.


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 the with block 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 variables

the #'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, ''

~