Package aerocalc :: Module unit_conversion
[frames] | no frames]

Source Code for Module aerocalc.unit_conversion

  1  #!/usr/bin/python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  # ############################################################################# 
  5  # Copyright (c) 2008, Kevin Horton 
  6  # All rights reserved. 
  7  # Redistribution and use in source and binary forms, with or without 
  8  # modification, are permitted provided that the following conditions are met: 
  9  # * 
 10  #     * Redistributions of source code must retain the above copyright 
 11  #       notice, this list of conditions and the following disclaimer. 
 12  #     * Redistributions in binary form must reproduce the above copyright 
 13  #       notice, this list of conditions and the following disclaimer in the 
 14  #       documentation and/or other materials provided with the distribution. 
 15  #     * The name of Kevin Horton may not be used to endorse or promote products 
 16  #       derived from this software without specific prior written permission. 
 17  # * 
 18  # THIS SOFTWARE IS PROVIDED BY KEVIN HORTON ``AS IS'' AND ANY EXPRESS OR 
 19  # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 
 20  # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 
 21  # EVENT SHALL KEVIN HORTON BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
 22  # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 23  # PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 24  # OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 25  # WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 26  # OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 27  # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 28  # ############################################################################# 
 29  # 
 30  # version 0.22, 25 Apr 2008 
 31  # 
 32  # Version History: 
 33  # vers     date     Notes 
 34  #  0.1   14 May 06  First release. Only has the unit conversions needed 
 35  #                   for the std_atm module: 
 36  #                   temperature, pressure, length and density. 
 37  # 
 38  # 0.11              Added speed conversion 
 39  # 
 40  # 0.20   06 May 07  Reworked to use default units from default_units module 
 41  # 
 42  # 0.21   24 Mar 08  Added fuel temperature to avgas_conv 
 43  # 
 44  # 0.22   25 Apr 08  Corrected error in unit validation in press_conv() 
 45  # ############################################################################# 
 46   
 47  """  
 48  Convert between various units. 
 49  """ 
 50   
 51  try: 
 52      from default_units import * 
 53  except ImportError: 
 54      default_area_units = 'ft**2' 
 55      default_power_units = 'hp' 
 56      default_speed_units = 'kt' 
 57      default_temp_units = 'C' 
 58      default_weight_units = 'lb' 
 59      default_press_units = 'in HG' 
 60      default_density_units = 'lb/ft**3' 
 61      default_length_units = 'ft' 
 62      default_alt_units = default_length_units 
 63      default_avgas_units = 'lb' 
 64      default_vol_units = 'ft**3' 
 65   
 66   
67 -def area_conv(A, from_units=default_area_units, 68 to_units=default_area_units):
69 """ 70 Convert area values between ft**2, in**2, m**2, km**2, sm**2 and nm**2. 71 72 The incoming value is first converted to ft**2, then it is converted to 73 desired return value. 74 75 76 The units default to those specified in default_units.py 77 78 Examples: 79 80 Convert 1 ft**2 to inches**2, with ft**2 already defined as the default 81 units: 82 >>> area_conv(1, to_units = 'in**2') 83 144.0 84 85 Convert 288 square inches to square feet, with ft**2 already defined as the default 86 units: 87 >>> area_conv(288, from_units = 'in**2') 88 2.0 89 90 Convert 10 square metres to square inches: 91 >>> area_conv(1000, from_units = 'm**2', to_units = 'in**2') 92 1550003.1000061999 93 """ 94 95 if from_units == 'ft**2': 96 pass 97 elif from_units == 'in**2': 98 A /= 144. 99 elif from_units == 'm**2': 100 A /= 0.3048 ** 2 101 elif from_units == 'km**2': 102 A /= 0.0003048 ** 2 103 elif from_units == 'sm**2': 104 A *= 5280. ** 2 105 elif from_units == 'nm**2': 106 A *= (1852 / 0.3048) ** 2 107 else: 108 raise ValueError, \ 109 'from_units must be "ft**2" or "in**2" or "m**2" or "km**2" or "sm**2" (square statute miles) or "nm**2" (square nautical miles).' 110 111 if to_units == 'ft**2': 112 return A 113 elif to_units == 'in**2': 114 return A * 144. 115 elif to_units == 'm**2': 116 return A * 0.3048 ** 2 117 elif to_units == 'km**2': 118 return A * 0.0003048 ** 2 119 elif to_units == 'sm**2': 120 return A / 5280. ** 2 121 elif to_units == 'nm**2': 122 return A * (0.3048 / 1852) ** 2 123 else: 124 raise ValueError, \ 125 'from_units must be "ft**2" or "in**2" or "m**2" or "km**2" or "sm**2" (square statute miles) or "nm**2" (square nautical miles).'
126 127
128 -def density_conv(D, from_units, to_units):
129 """ 130 Convert density values between kg/m**3, slug/ft**3 and lb/ft**3. 131 132 The incoming value is first converted to kg/m**3, then it is converted 133 to desired return value. 134 135 There are no default units. Both the from_units and the to_units must 136 be specified. 137 138 Example: 139 140 Convert 1.225 kg per metre cubed to lb per foot cubed: 141 >>> density_conv(1.225, from_units = 'kg/m**3', to_units = 'lb/ft**3') 142 0.076474253491112101 143 144 """ 145 146 if from_units == 'kg/m**3': 147 pass 148 elif from_units == 'slug/ft**3': 149 D *= 515.37882 150 elif from_units == 'lb/ft**3': 151 D *= 16.018463 152 else: 153 raise ValueError, \ 154 'from_units must be one of "kg/m**3", "slug/ft**3" and "lb/ft**3".' 155 156 if to_units == 'kg/m**3': 157 return D 158 elif to_units == 'slug/ft**3': 159 return D / 515.37882 160 elif to_units == 'lb/ft**3': 161 return D / 16.018463 162 else: 163 raise ValueError, \ 164 'to_units must be one of "kg/m**3", "slug/ft**3" and "lb/ft**3".'
165 166
167 -def force_conv(F, from_units=default_weight_units, 168 to_units=default_weight_units):
169 """ 170 Convert force values between lb and N. 171 172 The incoming value is first converted to N, then it is converted to the 173 desired return value. 174 """ 175 176 if from_units == 'N': 177 pass 178 elif from_units == 'lb': 179 F *= 4.4482216 180 else: 181 raise ValueError, 'from_units must be one of "lb" or "N".' 182 183 if to_units == 'N': 184 pass 185 elif to_units == 'lb': 186 F /= 4.4482216 187 else: 188 raise ValueError, 'to_units must be one of "lb" or "N".' 189 190 return F
191 192
193 -def len_conv(L, from_units=default_length_units, 194 to_units=default_length_units):
195 """ 196 Convert length values between ft, in, m, km, sm and nm. 197 198 The incoming value is first converted to ft, then it is converted to 199 desired return value. 200 201 The units default to those specified in default_units.py 202 203 Examples: 204 205 Convert 5280 ft to statute miles, with feet already defined as the default 206 units: 207 >>> len_conv(5280, to_units = 'sm') 208 1.0 209 210 Convert 1 nautical mile to feet, with feet already defined as the default 211 units: 212 >>> len_conv(1, from_units = 'nm') 213 6076.1154855643044 214 215 Convert 1000 metres to kilometres: 216 >>> len_conv(1000, from_units = 'm', to_units = 'km') 217 0.99999999999999989 218 """ 219 220 if from_units == 'ft': 221 pass 222 elif from_units == 'm': 223 L /= 0.3048 224 elif from_units == 'km': 225 L /= 0.0003048 226 elif from_units == 'sm': 227 L *= 5280. 228 elif from_units == 'nm': 229 L *= 1852 / 0.3048 230 elif from_units == 'in': 231 L /= 12. 232 else: 233 raise ValueError, \ 234 'from_units must be "ft", "in", "m", "km", "sm" (statute miles) or "nm" (nautical miles).' 235 236 if to_units == 'ft': 237 return L 238 elif to_units == 'm': 239 return L * 0.3048 240 elif to_units == 'km': 241 return L * 0.0003048 242 elif to_units == 'sm': 243 return L / 5280. 244 elif to_units == 'nm': 245 return (L * 0.3048) / 1852 246 elif to_units == 'in': 247 return L * 12. 248 else: 249 raise ValueError, \ 250 'from_units must be "ft", "in", "m", "km", "sm" (statute miles) or "nm" (nautical miles).'
251 252
253 -def power_conv(P, from_units=default_power_units, 254 to_units=default_power_units):
255 """ 256 Convert power values between horsepower, ft-lb/mn, ft-lb/s, watts, 257 kilowatts, BTU/hr and BTU/mn. 258 259 The incoming value is first converted to hp, then it is converted to the 260 desired return value. 261 The units default to those specified in default_units.py 262 263 """ 264 265 if from_units == 'hp': 266 pass 267 elif from_units == 'ft-lb/mn': 268 P /= 33000. 269 elif from_units == 'ft-lb/s': 270 P /= 550. 271 elif from_units == 'W': 272 P /= 745.69987 273 elif from_units == 'kW': 274 P /= 0.74569987 275 # elif from_units == 'BTU/hr': 276 # P /= 2544.4332 277 # elif from_units == 'BTU/mn': 278 # P /= 42.407227 279 else: 280 raise ValueError, \ 281 'from_units must be "hp", "ft-lb/mn", "ft-lb/s", "W" (watts), "kW" (kilowatts), "BTU/hr", or "BTU/mn".' 282 283 if to_units == 'hp': 284 return P 285 elif to_units == 'ft-lb/mn': 286 return P * 33000. 287 elif to_units == 'ft-lb/s': 288 return P * 550. 289 elif to_units == 'W': 290 return P * 745.69987 291 elif to_units == 'kW': 292 return P * 0.74569987 293 # elif to_units == 'BTU/hr': 294 # return P * 2544.4332 295 # elif to_units == 'BTU/mn': 296 # return P * 42.407227 297 else: 298 raise ValueError, \ 299 'to_units must be "hp", "ft-lb/mn", "ft-lb/s", "W" (watts), "kW" (kilowatts), "BTU/hr", or "BTU/mn".'
300 301
302 -def press_conv(P, from_units=default_press_units, 303 to_units=default_press_units):
304 """ 305 Convert pressure values between inches of HG, mm of HG, psi, lb/ft^2, 306 hpa and mb. 307 308 The incoming value is first converted to Pa, then it is converted to 309 desired return value. 310 The units default to those specified in default_units.py 311 312 313 Examples: 314 315 Convert 1013.25 hpa to default pressure units: 316 >>> press_conv(1013.25, from_units = 'hpa') 317 29.921331923765198 318 319 Convert 29.9213 default pressure units to mm of HG: 320 >>> press_conv(29.9213, to_units = 'mm HG') 321 760.00128931459176 322 323 Convert 2116.22 lb per sq. ft to lb per sq. inch: 324 >>> press_conv(2116.22, from_units = 'psf', to_units = 'psi') 325 14.695973160069311 326 """ 327 328 if from_units == 'in HG': 329 P *= 3386.38 # from NASA Reference Publication 1046 330 elif from_units == 'mm HG': 331 P *= 133.322 # derived from NASA Reference Publication 1046 value 332 elif from_units == 'psi': 333 P *= 6894.757 # derived from NASA Reference Publication 1046 value 334 elif from_units == 'psf' or from_units == 'lb/ft**2': 335 336 P *= 47.88026 # from NASA Reference Publication 1046 337 elif from_units == 'hpa' or from_units == 'mb': 338 P *= 100. 339 elif from_units == 'pa': 340 pass 341 else: 342 raise ValueError, \ 343 'from_units must be "in HG", "mm HG", "psi", "psf" (lb per sq. ft), "hpa", "mb" or "pa".' 344 345 if to_units == 'in HG': 346 return P / 3386.38 347 elif to_units == 'mm HG': 348 return P / 133.322 349 elif to_units == 'psi': 350 return P / 6894.757 351 elif to_units == 'psf' or to_units == 'lb/ft**2': 352 return P / 47.88026 353 elif to_units == 'hpa' or to_units == 'mb': 354 return P / 100. 355 elif to_units == 'pa': 356 return P 357 else: 358 raise ValueError, \ 359 'to_units must be "in HG", "mm HG", "psi", "psf" (lb per sq. ft), "pa", "hpa" or "mb".'
360 361
362 -def speed_conv(S, from_units=default_speed_units, 363 to_units=default_speed_units):
364 """ 365 Convert speed values between kt, mph, km/h, m/s and ft/s. 366 367 The incoming value is first converted to kt, then it is converted to 368 desired return value. 369 The units default to those specified in default_units.py 370 371 372 Example: 373 374 Convert 230 mph to kt: 375 >>> speed_conv(230, from_units = 'mph', to_units = 'kt') 376 199.86453563714903 377 378 """ 379 380 if from_units == 'kt': 381 pass 382 elif from_units == 'mph': 383 S *= len_conv(1, from_units='sm', to_units='nm') 384 elif from_units == 'km/h': 385 S *= len_conv(1, from_units='km', to_units='nm') 386 elif from_units == 'm/s': 387 S *= len_conv(1, from_units='m', to_units='nm') * 3600. 388 elif from_units == 'ft/s': 389 S *= len_conv(1, from_units=default_length_units, to_units='nm')\ 390 * 3600. 391 else: 392 raise ValueError, \ 393 'from_units must be one of "kt", "mph", "km/h", "m/s" and "ft/s".' 394 395 if to_units == 'kt': 396 return S 397 elif to_units == 'mph': 398 S *= len_conv(1, from_units='nm', to_units='sm') 399 return S 400 elif to_units == 'km/h': 401 S *= len_conv(1, from_units='nm', to_units='km') 402 return S 403 elif to_units == 'm/s': 404 S *= len_conv(1, from_units='nm', to_units='m') 405 return S / 3600. 406 elif to_units == 'ft/s': 407 S *= len_conv(1, from_units='nm', to_units=default_length_units) 408 return S / 3600. 409 else: 410 raise ValueError, \ 411 'to_units must be one of "kt", "mph", "km/h", "m/s" and "ft/s".'
412 413
414 -def temp_conv(T, from_units=default_temp_units, 415 to_units=default_temp_units):
416 """ 417 Convert absolute temperature values between deg C, F, K and R. 418 419 This function should not be used for relative temperature conversions, 420 i.e. temperature differences. 421 422 The incoming value is first converted to deg K, then it is converted to 423 desired return value. 424 The units default to those specified in default_units.py 425 426 427 Examples: 428 429 Convert 32 deg F to deg C, with deg C as the default units: 430 >>> temp_conv(32, from_units = 'F') 431 0.0 432 433 Convert 100 deg C to deg F, with deg C as the default units: 434 >>> temp_conv(100, to_units = 'F') 435 212.0 436 437 Convert 59 deg F to deg K 438 >>> temp_conv(59, from_units = 'F', to_units = 'K') 439 288.14999999999998 440 """ 441 442 if from_units == 'C': 443 T += 273.15 444 elif from_units == 'F': 445 T = ((T - 32) * 5.) / 9. + 273.15 446 elif from_units == 'K': 447 pass 448 elif from_units == 'R': 449 T *= 5. / 9. 450 else: 451 raise ValueError, \ 452 'from_units must be one of "C", "F", "K" or "R".' 453 454 if to_units == 'C': 455 return T - 273.15 456 elif to_units == 'F': 457 return (T - 273.15) * 1.8 + 32 458 elif to_units == 'K': 459 return T 460 elif to_units == 'R': 461 return T * 1.8 462 else: 463 raise ValueError, \ 464 'to_units must be one of "C", "F", "K" or "R".'
465 466
467 -def vol_conv(V, from_units=default_vol_units, 468 to_units=default_vol_units):
469 """ 470 Convert volume values between USG, ImpGal (Imperial gallons), l (litres), ft**3, in**3, m**3, km**3, sm**3 and nm**3. 471 472 The incoming value is first converted to ft**3, then it is converted to 473 desired return value. 474 475 476 The units default to those specified in default_units.py 477 478 Examples: 479 480 Convert 1 cubic foot to US gallons, with cubic feet already defined as 481 the default units: 482 >>> vol_conv(1, to_units = 'USG') 483 7.4805194804946105 484 485 Convert 1 Imperial gallon to cubic feet, with cubic feet already defined 486 as the default units: 487 >>> vol_conv(1, from_units = 'ImpGal') 488 0.16054365323600001 489 490 Convert 10 US gallon to litres: 491 >>> vol_conv(10, from_units = 'USG', to_units = 'l') 492 37.854117840125852 493 """ 494 495 if from_units == 'ft**3': 496 pass 497 elif from_units == 'in**3': 498 V /= 12. ** 3 499 elif from_units == 'm**3': 500 V /= 0.3048 ** 3 501 elif from_units == 'km**3': 502 V /= 0.0003048 ** 3 503 elif from_units == 'sm**3': 504 V *= 5280. ** 3 505 elif from_units == 'nm**3': 506 V *= (1852 / 0.3048) ** 3 507 elif from_units == 'USG': 508 V *= 0.133680555556 509 elif from_units == 'ImpGal': 510 V *= 0.160543653236 511 elif from_units == 'l': 512 V /= 3.048 ** 3 513 else: 514 raise ValueError, \ 515 'from_units must be "ft**3", "in**3", "USG", "ImpGal", "l", "m**3", "km**3", "sm**3" (cubic statute miles) or "nm**3" (cubic nautical miles).' 516 517 if to_units == 'ft**3': 518 return V 519 elif to_units == 'in**3': 520 return V * 12. ** 3 521 elif to_units == 'm**3': 522 return V * 0.3048 ** 3 523 elif to_units == 'km**3': 524 return V * 0.0003048 ** 3 525 elif to_units == 'sm**3': 526 return V / 5280. ** 3 527 elif to_units == 'nm**3': 528 return V * (0.3048 / 1852) ** 3 529 elif to_units == 'USG': 530 return V / 0.133680555556 531 elif to_units == 'ImpGal': 532 return V / 0.160543653236 533 elif to_units == 'l': 534 return V * 3.048 ** 3 535 else: 536 raise ValueError, \ 537 'to_units must be "ft**3", "in**3", "USG", "ImpGal", "l", "m**3", "km**3", "sm**3" (cubic statute miles) or "nm**3" (cubic nautical miles).'
538 539
540 -def wt_conv(W, from_units=default_weight_units, 541 to_units=default_weight_units):
542 """ 543 Convert weight values between lb and kg. 544 545 Purists will yell that lb is a unit of weight, and kg is a unit of mass. 546 Get over it. 547 548 The incoming value is first converted to kg, then it is converted to the 549 desired return value. 550 551 The units default to those specified in default_units.py 552 553 554 """ 555 556 if from_units == 'kg': 557 pass 558 elif from_units == 'lb': 559 W *= 0.453592 560 else: 561 raise ValueError, 'from_units must be one of "lb" or "kg".' 562 563 if to_units == 'kg': 564 pass 565 elif to_units == 'lb': 566 W *= 2.204622622 567 else: 568 raise ValueError, 'to_units must be one of "lb" or "kg".' 569 570 return W
571 572
573 -def avgas_conv( 574 AG, 575 from_units=default_avgas_units, 576 to_units=default_avgas_units, 577 temp=15, 578 temp_units='C', 579 grade='nominal', 580 ):
581 """ 582 Convert aviation gasoline between units of lb, US Gallon (USG), 583 Imperial Gallon (Imp Gal), litres (l) and kg, assuming nominal 584 density for aviation gasoline of 6.01 lb per USG. 585 586 The units default to those specified in default_units.py 587 588 Note: it was difficult to find authoritative values for aviation gasoline 589 density. Conventional wisdom is that aviation gasoline has a density of 590 6 lb/USG. The Canada Flight Supplement provides densities of: 591 temp density density density 592 (deg C) (lb/USG) (lb/ImpGal) (lb/l) 593 -40 6.41 7.68 1.69 594 -20 6.26 7.50 1.65 595 0 6.12 7.33 1.62 596 15 6.01 7.20 1.59 597 30 5.90 7.07 1.56 598 599 However, the Canada Flight Supplement does not provide a source for its 600 density data. And, the values for the different volume units are not 601 completly consistent, as they don't vary by exactly the correct factor. 602 For example, if the density at 15 deg C is 6.01 lb/USG, we would expect 603 the density in lb/ImpGal to be 7.22, (given that 1 ImpGal = 1.201 USG) 604 yet the Canada Flight Supplement has 7.20. 605 606 The only authoritative source for aviation gasoline density that was 607 found on the web was the \"Air BP Handbook of Products\" on the British 608 Petroleum (BP) web site: 609 610 <http://www.bp.com/liveassets/bp_internet/aviation/air_bp/STAGING/local_assets/downloads_pdfs/a/air_bp_products_handbook_04004_1.pdf> 611 612 It provides the following density data valid at 15 deg C (the BP document 613 only provides density in kg/m**3 - the density in lb/USG were calculated 614 by Kevin Horton): 615 Avgas density density 616 Type (kg/m**3) (lb/USG) 617 80 690 5.76 618 100 695 5.80 619 100LL 715 5.97 620 621 The available aviation gasoline specifications do not appear to define an 622 allowable density range. They do define allowable ranges for various 623 parametres of the distillation process - the density of the final product 624 will vary depending on where in the allowable range the refinery is run. 625 Thus there will be some variation in density from refinery to refinery. 626 627 This function uses the 15 deg C density values provided by BP, with the 628 variation with temperature provided in the Canada Flight Supplement. 629 630 The grade may be specified as \"80\", \"100\" or \"100LL\". It defaults to 631 \"100LL\" if it is not specified. 632 633 The temperature defaults to 15 deg C if it is not specified. 634 """ 635 636 lb_per_USG_15_nom = 6.01 # nominal density at 15 deg C from Canada Flight Supplement 637 slope = -0.007256 # change in density per deg C based on data from Canada Flight Supplement 638 639 lb_per_USG = lb_per_USG_15_nom * (1 + (slope * (temp_conv(temp, 640 from_units=temp_units, to_units='C') - 15)) 641 / lb_per_USG_15_nom) # density corrected for temperature, using nominal density value 642 643 if grade == 'nominal': 644 grade_density = lb_per_USG_15_nom 645 elif grade == '100LL': 646 grade_density = 5.967 647 elif str(grade) == '100': 648 grade_density = 5.801 649 elif str(grade) == '80': 650 grade_density = 5.7583 651 else: 652 raise ValueError, \ 653 'grade must be one of "nominal", "80", "100" or "100LL", with a default of "100LL"' 654 655 # Correct the density if the grade is other than nominal. 656 # If the grade actually is nominal, we are multiplying by 1 / 1 657 658 lb_per_USG *= grade_density / lb_per_USG_15_nom 659 660 if from_units == 'lb': 661 pass 662 elif from_units == 'USG': 663 AG *= lb_per_USG 664 elif from_units == 'ImpGal': 665 AG *= vol_conv(lb_per_USG, from_units='ImpGal', to_units='USG') 666 elif from_units == 'kg': 667 AG = wt_conv(AG, from_units='kg') 668 elif from_units == 'l': 669 AG *= vol_conv(lb_per_USG, from_units='l', to_units='USG') 670 else: 671 raise ValueError, \ 672 'from_units must be one of "lb", "USG", "Imp Gal", "l", or "kg".' 673 674 if to_units == 'lb': 675 pass 676 elif to_units == 'USG': 677 AG /= lb_per_USG 678 elif to_units == 'ImpGal': 679 AG /= vol_conv(lb_per_USG, from_units='ImpGal', to_units='USG') 680 elif to_units == 'kg': 681 AG = wt_conv(AG, to_units='kg') 682 elif to_units == 'l': 683 AG /= vol_conv(lb_per_USG, from_units='l', to_units='USG') 684 else: 685 raise ValueError, \ 686 'from_units must be one of "lb", "USG", "Imp Gal", "l", or "kg".' 687 688 return AG
689 690 691 if __name__ == '__main__': 692 693 # run doctest to check the validity of the examples in the doc strings. 694 695 import doctest 696 import sys 697 doctest.testmod(sys.modules[__name__]) 698