Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Conditional average from a text file. 2

Status
Not open for further replies.

rbubba117

Technical User
Jun 1, 2013
3
US
I'm a Fortran newbie and would appreciate some advice with a task I've been wanting to try. I need to create a simple Fortran program that calculates the average salary of individuals who make over $40,000. The individual's ID (column position: 7-12) is in one column and their salary (column position: 102-109) is in another, both of which are in a text file.

Could anyone please show me how to go about this using Fortran? My main question is how do I go about pulling in the text file data for manipulation? If anyone could provide a mini-mock up of what I'm trying to accomplish, I would be grateful!

I could easily do this in Excel, but I want to start learning more about Fortran.

Thanks for reading this.
 
Could you post as example some lines of the text file?
 
It kind of depends...

If your file is consistent and every row always has the same number of columns all the time, you can simply read every one of the values with a list directed READ.

If the file is not 100% consistent and some rows may have missing data, then, the best thing to do is to declared a character string variable of about 150 characters long (or whatever length you need), read your file one entire line at a time into this string and then perform internal reads from it to retrieve the data from the specific columns:
READ(*,'(a150)') line
READ(line(7:12),*) EmpID
READ(line(102:109),*) EmpSalary
where EmpId and EmpSalary have been declared to be character and real variables, respectively.

Other than that, please first give a try to your program and THEN we can help...it should be an easy program of no more than 20 lines.
 
Thanks for the help so far!

Here's the data from the text file:
111223333 50000
222334444 32000
555998888 45000

With some research on the fly, I've been able to come up with the following block of code:

program AvgSalCheck
implicit none
character(30) :: SalFile
character :: EmpID
real :: line
real :: EmpSalary
SalFile = 'AvgSal.txt'
open(1,file=SalFile)
read(*,'(a150)')line
read(line(1:9),*)EmpID
read(line(11:15),*)EmpSalary
print *,sum(EmpSalary,EmpSalary>40000)/(max(1,count(EmpSalary>40,000))
end program AvgSalCheck


However, I get the following output message:

C:\Users\Ray\Desktop\fortranprograms\AvgSalCheck.F95(8) : warning 868 - Opening unit 1 may affect the operation of input from the default unit '*' - are you sure you want to do this?
C:\Users\Ray\Desktop\fortranprograms\AvgSalCheck.F95(10) : error 249 - Colon found where not expected
C:\Users\Ray\Desktop\fortranprograms\AvgSalCheck.F95(11) : error 249 - Colon found where not expected
Compilation failed.

Any further help would be appreciated!

P.S. The way I set up the new text file, the info I want is in lines (1:9) and (11:15).
 
In your code above line should be string and not how you declared:
real :: line

If your EmpID and EmpSalary are numeric, you can simply do
read(*,*)EmpID, EmpSalary
but you should use a loop.
 
Let us add that the intrinsic functions SUM and COUNT expect, as main argument an array, not a scalar => EmpSalary must be an array you can fulfill using a loop for instance.

Code:
program AvgSalCheck

implicit none

INTEGER :: n
REAL :: EmpSalary(1000) ! 1000 is assumed to be an overestimation of the number of lines
INTEGER :: EmpID(1000)

open(10,file='AvgSal.txt')

n=0
DO
  n=n+1
  read(10,*,end=100) EmpID(n),EmpSalary(n)
ENDDO
100 CONTINUE ! the new location after an end of file
n=n-1

print *,sum(EmpSalary(1:n),EmpSalary(1:n)>40000)/max(1,count(EmpSalary(1:n)>40000))
end program

It is also possible to solve your problem without using any array in summing within the loop :

Code:
program AvgSalCheck

implicit none

INTEGER :: n,EmpID
REAL :: EmpSalary,SumSalary

open(10,file='AvgSal.txt')

n=0
SumSalary=0
do
  read(10,*,end=100) EmpID,EmpSalary
  if(EmpSalary > 40000) then
    SumSalary=sumSalary+EmpSalary
    n=n+1
  endif
enddo
100 CONTINUE ! the new location after an end of file

print *,SumSalary/max(1,n)
end program


François Jacq
 

Do not forget the premise about the real file...I think the one above is just a mock up file...the real one is over 100 columns wide and has other quantities and strings in between.

I think the code should look more along the lines of:
Code:
program AvgSalCheck

implicit none

INTEGER :: n
REAL :: EmpSalary(1000) ! 1000 is assumed to be an overestimation of the number of lines
INTEGER :: EmpID(1000)
character(150) :: line

open(10,file='AvgSal.txt')

n=0
DO
  n=n+1
  read(10,'(a150)'),end=100) line 
  read(line(1:9),*) EmpID(n)
  read(line(11:15),*) EmpSalary(n)
ENDDO
100 CONTINUE ! the new location after an end of file
n=n-1

print *,sum(EmpSalary(1:n),EmpSalary(1:n)>40000)/max(1,count(EmpSalary(1:n)>40000))
end program
 
Thank you so much, everyone! I'm looking forward to learning more about Fortran.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top