windchill table using nested loop

2019-08-02 07:53发布

问题:

I'm writing a program that prints a table with the windchill index. Every windchill value should be adequate to a corresponding row and column.

def main():    
    windSpeed = 0
    temp = 0
    windChill = 35.74 + (0.6215 * temp) - 35.75 * (windSpeed ** 0.16) \
            + 0.4275 * temp * (windSpeed ** 0.16)

    # table frame, temps
    for temp in range(-20, 70, 10):
        print 2 * " ", temp, 
    print "\n", " " * 2, "-" * 51    

    #table frame, speeds
    for windSpeed in range (0, 35, 5):
        print windSpeed


main()

This produces:

  -20    -10    0    10    20    30    40    50    60 
  ---------------------------------------------------
0
5
10
15
20
25
30

Obviously, the hard part is to actually print the windchill values. I've been playing with the code quite a bit and it only prints out the first windchill value with its coefficients' values of 0 and 0, which are defined at the very beggining of the program.

回答1:

Since it's impossible go back and change lines already printed afterwards, you need to compute the wind-chills at the same time you print out each row of the table. Rather than repeat the longish expression for each of the temperature and wind speed combinations that appear in each row, it's better to create a separate function which calculates the value from them and then call it by (its much shorter) name repeatedly.

The built-in string method format() makes it relatively simple to display all the data being computed the desired way—so taking the time to learn how it works would be a very worthwhile endeavor.

Here's code which does this that also tries to follow the PEP 8 - Style Guide for Python Code.

def wind_chill(temp, wind_speed):
    """ Compute wind chill given temperature and wind speed if the
        temperature is 50 degrees Fahrenheit or less and the wind speed is
        above 3 mph, otherwise return 'nan' (not-a-number) because it's an
        undefined quantity in those situations.
    """
    return (35.74 + (0.6215 * temp) - 35.75 * (wind_speed ** 0.16)
            + 0.4275 * temp * (wind_speed ** 0.16)
                if temp <= 50 and wind_speed > 3 else
            float('nan'))

def main():
    # print table header
    temps = xrange(-20, 70, 10)
    num_temps = len(temps)
    data = [" "] + [temp for temp in temps]
    print ("{:3s}" + num_temps * " {:5d}").format(*data)
    data = [" "] + num_temps * [5 * "-"]
    print ("{:3s}" + num_temps * " {:5s}").format(*data)

    # print table rows
    row_format_string = "{:3d}" + num_temps * " {:5.1F}"
    for wind_speed in xrange(0, 35, 5):
        data = [wind_speed] + [wind_chill(temp, wind_speed) for temp in temps]
        print row_format_string.format(*data)

main()

Output:

      -20   -10     0    10    20    30    40    50    60
    ----- ----- ----- ----- ----- ----- ----- ----- -----
  0   NAN   NAN   NAN   NAN   NAN   NAN   NAN   NAN   NAN
  5 -34.0 -22.3 -10.5   1.2  13.0  24.7  36.5  48.2   NAN
 10 -40.7 -28.3 -15.9  -3.5   8.9  21.2  33.6  46.0   NAN
 15 -45.0 -32.2 -19.4  -6.6   6.2  19.0  31.8  44.6   NAN
 20 -48.2 -35.1 -22.0  -8.9   4.2  17.4  30.5  43.6   NAN
 25 -50.8 -37.5 -24.1 -10.7   2.6  16.0  29.4  42.8   NAN
 30 -53.0 -39.4 -25.9 -12.3   1.3  14.9  28.5  42.0   NAN


回答2:

You need to loop through all values of both temp and windspeed, recalculating wind chill each time. A nice way to do this may be to redefine windChill as a function. To get the table to print with the correct spacing you can use string formatting.

def main():    
    def wind_chill(temp, wind_speed):
        return 35.74 + (0.6215 * temp) - 35.75 * (wind_speed ** 0.16) \
            + 0.4275 * temp * (wind_speed ** 0.16)

    heading = '  '
    for temp in range(-20, 70, 10):
        heading += "{:>7d}".format(temp)
    print heading + "\n   " + "-" * 62    
    for wind_speed in range (0, 35, 5):
        output_line = "{:>2d}".format(wind_speed)
        for temp in range(-20, 70, 10):
            output_line += "{:>7.1f}".format(wind_chill(temp, wind_speed))
        print output_line

main()

Alternatively set all of the data in a 2d array (list of lists) first and then print it out using a single long format string. (This uses sum to flatten the list of lists into a single long sequence.)

def main():    
    temps = range(-20, 70, 10)
    winds = range(0, 35, 5)
    chill = [[w] + [35.74 + .6215 * t - 35.75 * w**.16 + .4275 * t * w**.16 
                   for t in temps] for w in winds]
    rows = len(winds)
    cols = len(temps)
    print ('  ' + '{:7d}' * cols + '\n  ' + '-' * cols * 7
           + ('\n{:2d}' + '{:7.1f}' * cols) * rows).format(*sum(chill, temps))