带有 CSV 输入的 REXX 代码

REXX codin with CSV input

我是 REXX 编码的新手,我需要编写一个程序来查找每个月的最高、最低和平均温度。

输入以逗号分隔,如下所示:

DAY/MONTH,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec      
1st,25.9,25.4,31.3,22.4,8.1,7.3,12.9,13.1,11.3,15.2,19.2,21    
2nd,27.2,22.3,18,14.6,10.2,10.9,10.9,13.5,15.9,24.9,26.2,17.2  
3rd,34.9,16.6,19.1,20.8,10.6,10.7,7,11.1,14.5,25.1,28.9,22.9   
4th,24.4,19.8,21.7,12.6,11.5,13,10.5,7.3,13.1,22.5,16.8,21.7   
5th,14.1,21.8,18.9,14.4,15.4,11.7,10.5,8.4,14,11.4,13.8,23.4
... etc

我需要创建 REXX 代码来查找每个月的最高、最低和平均温度并如下所示

User,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec
Max,34.9,16.6,19.1,20.8,10.6,10.7,7,11.1,14.5,25.1,28.9,22.9   
Min,24.4,19.8,21.7,12.6,11.5,13,10.5,7.3,13.1,22.5,16.8,21.7   
Mean,14.1,21.8,18.9,14.4,15.4,11.7,10.5,8.4,14,11.4,13.8,23.4

在创建 REXX 代码或任何 literature/direction 方面的帮助将不胜感激。

到目前为止我的代码是

/*REXX*/                                                                
/* TRACE ?I */                                                          
ADDRESS SYSCALL "READFILE /u/inputdata RECS."                      
                                                                        
IF RC <> 0 THEN DO                                                      
  SAY "ERROR READING FILE"                                              
  EXIT                                                                  
 END                                                                    
                                                                        
 FS=",";  MAXTEMP=""; MINTEMP=""; AVGTEMP=""                            
 DO I = 2 TO RECS.0                                                     
   PARSE VAR RECS.I DAY","JAN","FEB","MAR","APR","JUN","JUL","AUG","SEP","OCT","NOV,"DEC
     DO J = 2 TO RECS.I                                                 
           MAXTEMP = MAX(RECS.I)    /*Needs to add another VAR into Maxtemp*/
           MINTEMP = MIN(RECS.I)    /*same but Min                         */
           AVGTEMP = SUM(RECS.I)/COUNT(RECS.I)  /*Total/The amount of days*/ 
        END                                                                
    END                                                                    
 SAY user, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
 SAY MAX, MAXTEMP        /*MAX for each month fill out*/               
 SAY MIN, MINTEMP        /*Min                        */               
 SAY MEAN, AVGTEMP       /*Avg                        */               
END                                                                    

我正在尝试为 MaxTemp、MinTemp 和 MeanTemp 创建一个变量,随着循环的进行添加月份。

这是一个可能的实现。它像您一样遍历每条记录;这是外循环(循环变量 ii)。那么每个月的当前温度是

  1. 与该月的当前最大值相比,如果大于则存储
  2. 与该月的当前最低值相比,如果低于该值则存储
  3. 添加到当月的平均汇总字段

这是内部循环(lop变量jj)。 注意此内部循环中的代码注意不会处理超出每月最大天数的天数的值。

由于数据的年份似乎未知,因此无法计算出 2 月的正确天数。如果年份已知,您需要添加它。

/*REXX*/                                                                
/* TRACE ?I */
address syscall "readfile /u/inputdata Recs."

if RC <> 0 
then do                                                      
    say "ERROR READING FILE"                                              
    exit 16                                                                  
    end                                                                    
                                                                        
ifs = ","  /* Field separator for parsing input records */
ofs = ","  /* field separator for writing output records */

/* Initialize arrays to aggregate temperature data by month */
MaxTemp. = 0
MinTemp. = 99999
AvgTemp. = 0                           

/* Initialize array of number of days per month */
/* We do not know the year, so we cannot calculate whether February has 28 or 29 days */
DaysPerMonth.1  = 31
DaysPerMonth.2  = 28 /* Need to be adjusted for leap years */
DaysPerMonth.3  = 31
DaysPerMonth.4  = 30
DaysPerMonth.5  = 31
DaysPerMonth.6  = 30
DaysPerMonth.7  = 31
DaysPerMonth.8  = 31
DaysPerMonth.9  = 30
DaysPerMonth.10 = 31
DaysPerMonth.11 = 30
DaysPerMonth.12 = 31
 
/* Split (parse) each input record and fill the DayTemp array with daily temperatures by month */ 

do ii = 2 to Recs.0
    parse var Recs.ii DayNum (ifs) DayTemp.1 (ifs) DayTemp.2  (ifs) DayTemp.3  (ifs) DayTemp.4  ,
                             (ifs) DayTemp.5 (ifs) DayTemp.6  (ifs) DayTemp.7  (ifs) DayTemp.8  ,
                             (ifs) DayTemp.9 (ifs) DayTemp.10 (ifs) DayTemp.11 (ifs) DayTemp.12 .
                
    /* For each month, adjust min and max values, and sum up for building average later on */
    do jj =  1 to 12

        /* Don't process values for day numbers greater that number of days in month */
        if ( ii - 1 ) <= DaysPerMonth.jj
        then do

            if MaxTemp.jj < DayTemp.jj
            then MaxTemp.jj = DayTemp.jj
        
            if MinTemp.jj > DayTemp.jj
            then MinTemp.jj = DayTemp.jj
        
            AvgTemp.jj = AvgTemp.jj + DayTemp.jj
                          
            end /* if ( ii - 1 ) ... */
            
        end /* do jj = 1 to 12 */
                            
    end /* do ii = 1 to 12 */
    

Heading = "User,Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec"
Maxima  = "Max"
Minima  = "Min"
Means   = "Mean"

/* Build the min, max and average records by appending value by value */

do ii = 1 to 12
    Maxima = Maxima || ofs || format( MaxTemp.ii, 2, 1 )
    Minima = Minima || ofs || format( MinTemp.ii, 2, 1 )
    Means  = Means  || ofs || format( ( AvgTemp.ii / DaysPerMonth.ii ), 2, 1 )
    end 
  
/* Write heading, min, max, and average records */  
say Heading
say Maxima
say Minima
say Means 

提示:不要使用单字母变量名,因为您无法搜索或搜索并替换此类名称。我总是为循环变量或临时变量使用双字母变量名,例如 ii、jj、kk 等。这些(很可能)从未出现在任何其他上下文的代码中,因此可以轻松地进行搜索和替换.