Coverage for pygeodesy/interns.py: 99%

1# -*- coding: utf-8 -*-

2

3 u'''Single C{str}ing constants, C{intern}'ed across C{pygeodesy}

4 modules and function L{pygeodesy.machine}.

5'''

6 import sys as _sys # in .internals, .lazily

7 try:

8 _intern = intern # PYCHOK in .lazily, .trf

9 except NameError: # Python 3+

10 _intern = _sys.intern

11

12 _COMMASPACE_ = ', ' # overriden below

13 _SUB_PACKAGES = 'auxilats', 'deprecated', 'geodesicx', 'rhumb', 'triaxials' # PYCHOK in ...

14# ... .lazily, make._dist, MANIFEST, setup.setup, test/bases, test/testModules

15

16

17 class _Dash(str):

18 '''(INTERNAL) Extended C{str} for prefix_DASH_.

19 '''

20 def __call__(self, *args):

21 '''Join C{self} plus all B{C{args}} like C{'-'.join((self,) + B{args})}.

22 '''

23 return _DASH_(self, *args) # re-callable

24

25

26 class _Int(int):

27 '''(INTERNAL) Unique C{int}.

28 '''

29 pass

30

31

32 class Str_(str):

33 '''Extended, I{callable} C{str} class, not nameable.

34

35 @see: Nameable and callable class L{Str<pygeodesy.unitsBase.Str>}.

36 '''

37 def join_(self, *args):

38 '''Join all positional B{C{args}} like C{self.join(B{args})}.

39

40 @return: All B{C{args}} joined by this instance (L{Str_}).

41

42 @note: An other L{Str_} instance is returned to make the

43 result re-callable.

44 '''

45 return Str_(str.join(self, map(str, args))) # re-callable

46

47 __call__ = join_

48

49 NN = Str_('') # PYCHOK Nomen Nescio <https://Wiktionary.org/wiki/N.N.>

50

51

52 class _Prefix(Str_):

53 '''(INTERNAL) Extended C{str} for prefix.

54 '''

55 def __call__(self, *args):

56 '''Join C{self} plus all B{C{args}} like C{" ".join((self,) + B{args})}.

57 '''

58 return _SPACE_.join_(self, *args) # re-callable

59

60

61 class _PyPy__(str): # overwritten by singleton below

62 '''(INTERNAL) Extended C{str} for C{"PyPy"} and version.

63 '''

64 def __call__(self, version=NN):

65 '''Return C{"PyPy <version>"} or C{NN}.

66 '''

67 v = version or _sys.version

68 if _PyPy__ in v:

69 v = v.split(_PyPy__)[1].split(None, 1)[0] # == _DOT_.join(_sys.pypy_version_info[:3])

70 return NN(_PyPy__, v)

71 else:

72 return NN

73

74

75 class _Python_(str): # overwritten by singleton below

76 '''(INTERNAL) Extended C{str} for C{"Python"} and version.

77 '''

78 def __call__(self, version=NN):

79 '''Return C{"Python <version>"}.

80 '''

81 v = version or _sys.version

82 return _SPACE_(self, v.split(None, 1)[0])

83

84

85 class _Range(str):

86 '''(INTERNAL) Extended C{str} for C{range} strings.

87 '''

88 def __call__(self, lo, hi, lopen=False, ropen=False,

89 prec=0, sep=_COMMASPACE_):

90 '''Return the range as C{"(lo, hi)"}, C{"(lo, hi]"},

91 C{"[lo, hi)"} or C{"[lo, hi]"}.

92 '''

93 from pygeodesy.streprs import Fmt

94 r = NN(Fmt.f(lo, prec=prec), sep,

95 Fmt.f(hi, prec=prec))

96 f = (Fmt.PAREN if ropen else Fmt.LOPEN) if lopen else \

97 (Fmt.ROPEN if ropen else Fmt.SQUARE)

98 return f(r)

99

100

101 class _Slicer(str):

102 '''(INTERNAL) String slicer C{.fromX} or C{.tillY}.

103 '''

104 def __getattr__(self, name): # .fromX, .tillY

105 n = len(name) - 4

106 if n > 0:

107 # assert len('till') == len(_from_) == 4

108 if name.startswith('till'):

109 i = self.find(name[4:])

110 return self if i < 0 else _Slicer(self[:i + n])

111 elif name.startswith(_from_):

112 i = self.find(name[4:])

113 return self if i < 0 else _Slicer(self[i:])

114 return str.__getattr__(self, name) # PYCHOK no cover

115

116

117 class MISSING(object):

118 '''(INTERNAL) Singleton C{str}.

119 '''

120 def __init__(self):

121 self.__name__ = type(self).__name__

122

123 def toRepr(self, **unused):

124 return type(self).__name__

125

126 __repr__ = __str__ = toStr = toRepr

127

128 MISSING = MISSING() # PYCHOK singleton

129

130# __DUNDER__-style names would get mangled in classes

131 _0_ = '0' # PYCHOK 'zero'

132 _0to9_ = '0123456789' # PYCHOK OK

133 _1_ = '1' # PYCHOK OK

134 _2_ = '2' # PYCHOK OK

135 _3_ = '3' # PYCHOK OK

136 _4_ = '4' # PYCHOK OK

137 _a_ = 'a' # PYCHOK OK

138 _A_ = 'A' # PYCHOK OK

139 _a12_ = 'a12' # PYCHOK OK

140 _area_ = 'area' # PYCHOK OK

141 _Airy1830_ = 'Airy1830' # PYCHOK OK

142 _AiryModified_ = 'AiryModified' # PYCHOK OK

143 _ambiguous_ = 'ambiguous' # PYCHOK OK

144 _AMPERSAND_ = Str_('&') # PYCHOK OK

145 _an_ = 'an' # PYCHOK OK

146 _and_ = 'and' # PYCHOK OK

147# _AND_ = _AMPERSAND_ # PYCHOK OK

148 _angle_ = 'angle' # PYCHOK OK

149 _antipodal_ = 'antipodal' # PYCHOK OK

150 _arg_ = 'arg' # PYCHOK OK

151# _ASTERISK_ = _STAR_ # PYCHOK OK

152 _AT_ = Str_('@') # PYCHOK OK

153 _AtoZnoIO_ = _Slicer('ABCDEFGHJKLMNPQRSTUVWXYZ') # PYCHOK in .gars, .mgrs and .wgrs

154 _attribute_ = 'attribute' # PYCHOK OK

155 _azi1_ = 'azi1' # PYCHOK OK

156 _azi12_ = 'azi12' # PYCHOK OK

157 _azi2_ = 'azi2' # PYCHOK OK

158 _azimuth_ = 'azimuth' # PYCHOK OK

159 _b_ = 'b' # PYCHOK OK

160 _B_ = 'B' # PYCHOK OK

161 _BACKSLASH_ = Str_('\\') # PYCHOK OK

162 _band_ = 'band' # PYCHOK OK

163 _BANG_ = Str_('!') # PYCHOK OK

164 _BAR_ = Str_('|') # PYCHOK OK

165 _bearing_ = 'bearing' # PYCHOK OK

166 _Bessel1841_ = 'Bessel1841' # PYCHOK OK

167 _beta_ = 'beta' # PYCHOK OK

168 _by_ = 'by' # PYCHOK OK

169 _c_ = 'c' # PYCHOK OK

170 _C_ = 'C' # PYCHOK OK

171 _cartesian_ = 'cartesian' # PYCHOK OK

172 _center_ = 'center' # PYCHOK OK

173# _CIRCUMFLEX_ = Str_('^') # PYCHOK OK

174 _Clarke1866_ = 'Clarke1866' # PYCHOK OK

175 _Clarke1880IGN_ = 'Clarke1880IGN' # PYCHOK OK

176 _clip_ = 'clip' # PYCHOK OK

177 _clipid_ = 'clipid' # PYCHOK OK

178 _coincident_ = 'coincident' # PYCHOK OK

179 _colinear_ = 'colinear' # PYCHOK OK

180 _COLON_ = Str_(':') # PYCHOK OK

181 _COLONSPACE_ = Str_(': ') # PYCHOK OK

182 _COMMA_ = Str_(',') # PYCHOK OK

183 _COMMASPACE_ = Str_(_COMMASPACE_) # PYCHOK OK

184 _composite_ = 'composite' # PYCHOK OK

185 _concentric_ = 'concentric' # PYCHOK OK

186 _convergence_ = _Prefix('convergence') # PYCHOK OK

187 _conversion_ = 'conversion' # PYCHOK OK

188 _convex_ = 'convex' # PYCHOK OK

189 _d_ = 'd' # PYCHOK OK

190 _D_ = 'D' # PYCHOK OK

191 _DALL_ = '__all__' # PYCHOK _DUNDER_(NN, 'all', NN)

192 _DASH_ = Str_('-') # PYCHOK == _MINUS_

193 _datum_ = 'datum' # PYCHOK OK

194 _decode3_ = 'decode3' # PYCHOK OK

195 _deg_ = 'deg' # PYCHOK OK

196 _degrees_ = 'degrees' # PYCHOK OK

197 _degrees2_ = 'degrees2' # PYCHOK SQUARED

198 _delta_ = 'delta' # PYCHOK OK

199 _DEPRECATED_ = 'DEPRECATED' # PYCHOK OK

200 _DEQUALSPACED_ = Str_(' == ') # PYCHOK OK

201 _distance_ = 'distance' # PYCHOK OK

202 _distant_ = _Prefix('distant') # PYCHOK OK

203 _DMAIN_ = '__main__' # PYCHOK _DUNDER_(NN, 'main', NN)

204 _DNAME_ = '__name__' # PYCHOK _DUNDER_(NN, _name_, NN)

205 _doesn_t_exist_ = "doesn't exist" # PYCHOK OK

206 _DOT_ = Str_('.') # PYCHOK OK

207 _duplicate_ = 'duplicate' # PYCHOK OK

208 _e_ = 'e' # PYCHOK OK

209 _E_ = 'E' # PYCHOK OK

210 _earth_ = 'earth' # PYCHOK OK

211 _easting_ = 'easting' # PYCHOK OK

212 _ecef_ = 'ecef' # PYCHOK OK

213 _edge_ = 'edge' # PYCHOK OK

214 _elevation_ = 'elevation' # PYCHOK OK

215 _ELLIPSIS_ = Str_('...') # PYCHOK OK

216 _ELLIPSIS4_ = Str_('....') # PYCHOK OK

217# _ELLIPSISPACED_ = Str_(' ... ') # PYCHOK <https://www.ThePunctuationGuide.com/ellipses.html>

218 _ellipsoid_ = 'ellipsoid' # PYCHOK OK

219 _ellipsoidal_ = 'ellipsoidal' # PYCHOK OK

220 _encode_ = 'encode' # PYCHOK OK

221 _end_ = 'end' # PYCHOK OK

222 _epoch_ = 'epoch' # PYCHOK OK

223 _EQUAL_ = Str_('=') # PYCHOK OK

224 _EQUALSPACED_ = Str_(' = ') # PYCHOK OK

225 _Error_ = 'Error' # PYCHOK OK

226 _exceed_PI_radians_ = 'exceed PI radians' # PYCHOK OK

227 _exceeds_ = _Prefix('exceeds') # PYCHOK OK

228# _EXCLAMATION_ = _BANG_ # PYCHOK OK

229 _exists_ = 'exists' # PYCHOK OK

230 _f_ = 'f' # PYCHOK OK

231 _F_ = 'F' # PYCHOK OK

232 _feet_ = 'feet' # PYCHOK OK

233 _few_ = 'few' # PYCHOK OK

234 _fi_ = 'fi' # PYCHOK OK

235 _finite_ = 'finite' # PYCHOK OK

236 _from_ = 'from' # PYCHOK OK

237 _g_ = 'g' # PYCHOK OK

238 _gamma_ = 'gamma' # PYCHOK OK

239 _GRS80_ = 'GRS80' # PYCHOK OK

240 _h_ = 'h' # PYCHOK OK

241 _H_ = 'H' # PYCHOK OK

242 _HASH_ = '#' # PYCHOK OK

243 _height_ = 'height' # PYCHOK OK

244 _hemipole_ = 'hemipole' # PYCHOK OK

245 _i_ = 'i' # PYCHOK OK

246 _immutable_ = 'immutable' # PYCHOK OK

247 _in_ = 'in' # PYCHOK OK

248 _incompatible_ = 'incompatible' # PYCHOK OK

249 _INF_ = 'INF' # PYCHOK OK

250 _infinite_ = 'infinite' # PYCHOK _not_finite_

251 _initial_ = 'initial' # PYCHOK OK

252 _inside_ = 'inside' # PYCHOK OK

253 _insufficient_ = 'insufficient' # PYCHOK OK

254 _intersection_ = 'intersection' # PYCHOK OK

255 _Intl1924_ = 'Intl1924' # PYCHOK OK

256 _INV_ = 'INV' # PYCHOK INValid

257 _invalid_ = 'invalid' # PYCHOK OK

258 _invokation_ = 'invokation' # PYCHOK OK

259 _j_ = 'j' # PYCHOK OK

260 _k0_ = 'k0' # PYCHOK OK

261 _keyword_ = 'keyword' # PYCHOK OK

262 _kind_ = 'kind' # PYCHOK OK

263 _Krassovski1940_ = 'Krassovski1940' # PYCHOK OK

264 _Krassowsky1940_ = 'Krassowsky1940' # PYCHOK OK

265 _LANGLE_ = '<' # PYCHOK OK

266 _lam_ = 'lam' # PYCHOK OK

267 _lat_ = 'lat' # PYCHOK OK

268 _lat0_ = 'lat0' # PYCHOK OK

269 _lat1_ = 'lat1' # PYCHOK OK

270 _lat2_ = 'lat2' # PYCHOK OK

271 _latlon_ = 'latlon' # PYCHOK OK

272 _LatLon_ = 'LatLon' # PYCHOK OK

273 _LCURLY_ = '{' # PYCHOK LBRACE

274 _len_ = 'len' # PYCHOK OK

275 _limit_ = 'limit' # PYCHOK OK

276 _line_ = 'line' # PYCHOK OK

277 _LPAREN_ = '(' # PYCHOK OK

278 _lon_ = 'lon' # PYCHOK OK

279 _lon0_ = 'lon0' # PYCHOK OK

280 _lon1_ = 'lon1' # PYCHOK OK

281 _lon2_ = 'lon2' # PYCHOK OK

282 _low_ = 'low' # PYCHOK OK

283 _LSQUARE_ = '[' # PYCHOK LBRACK

284 _ltp_ = 'ltp' # PYCHOK OK

285 _m_ = 'm' # PYCHOK OK

286 _M_ = 'M' # PYCHOK OK

287 _m12_ = 'm12' # PYCHOK OK

288 _M12_ = 'M12' # PYCHOK OK

289 _M21_ = 'M21' # PYCHOK OK

290 _MANT_DIG_ = 'MANT_DIG' # PYCHOK OK

291 _MAX_ = 'MAX' # PYCHOK OK

292 _mean_ = 'mean' # PYCHOK OK

293 _meanOf_ = 'meanOf' # PYCHOK OK

294 _meridional_ = 'meridional' # PYCHOK OK

295 _meter_ = 'meter' # PYCHOK OK

296 _meter2_ = 'meter2' # PYCHOK SQUARED

297 _MGRS_ = 'MGRS' # PYCHOK OK

298 _MIN_ = 'MIN' # PYCHOK OK

299 _MINUS_ = _DASH_ # PYCHOK OK

300 _module_ = 'module' # PYCHOK OK

301 _n_ = 'n' # PYCHOK OK

302 _N_ = 'N' # PYCHOK OK

303 _n_a_ = 'n/a' # PYCHOK OK

304 _N_A_ = 'N/A' # PYCHOK OK

305 _NAD27_ = 'NAD27' # PYCHOK OK

306 _NAD83_ = 'NAD83' # PYCHOK OK

307 _name_ = 'name' # PYCHOK OK

308 _NAN_ = 'NAN' # PYCHOK OK

309 _near_ = _Dash('near') # PYCHOK OK

310 _nearestOn2_ = 'nearestOn2' # PYCHOK OK

311 _negative_ = 'negative' # PYCHOK OK

312 _NL_ = Str_('\n') # PYCHOK OK

313 _NLATvar_ = Str_(_NL_ + '@var ') # PYCHOK OK

314 _NLHASH_ = Str_(_NL_ + '# ') # PYCHOK OK

315 _NN_ = 'NN' # PYCHOK OK

316 _no_ = _Prefix('no') # PYCHOK OK

317 _northing_ = 'northing' # PYCHOK OK

318 _not_ = _Prefix('not') # PYCHOK OK

319 _NOTEQUAL_ = _BANG_ + _EQUAL_ # PYCHOK OK

320 _not_finite_ = 'not finite' # PYCHOK _not_(_finite_), _infinite_

321 _not_scalar_ = 'not scalar' # PYCHOK _not_(_scalar_)

322 _NTF_ = 'NTF' # PYCHOK OK

323 _null_ = 'null' # PYCHOK OK

324 _number_ = 'number' # PYCHOK OK

325 _numpy_ = 'numpy' # PYCHOK OK

326 _Nv00_ = 'Nv00' # PYCHOK OK

327 _odd_ = 'odd' # PYCHOK OK

328 _of_ = 'of' # PYCHOK OK

329 _on_ = 'on' # PYCHOK OK

330 _opposite_ = 'opposite' # PYCHOK OK

331 _or_ = 'or' # PYCHOK OK

332 _other_ = 'other' # PYCHOK OK

333 _outside_ = 'outside' # PYCHOK OK

334 _overlap_ = 'overlap' # PYCHOK OK

335 _parallel_ = 'parallel' # PYCHOK OK

336 _PERCENT_ = '%' # PYCHOK OK

337 _PERCENTDOTSTAR_ = '%.*' # PYCHOK _DOT_(_PERCENT_, _STAR_)

338 _phi_ = 'phi' # PYCHOK OK

339 _PLUS_ = Str_('+') # PYCHOK OK

340 _PLUSMINUS_ = _PLUS_ + _MINUS_ # PYCHOK OK

341 _point_ = 'point' # PYCHOK OK

342 _points_ = 'points' # PYCHOK OK

343 _pole_ = 'pole' # PYCHOK OK

344 _precision_ = 'precision' # PYCHOK OK

345 _prime_vertical_ = 'prime_vertical' # PYCHOK OK

346 _pygeodesy_ = 'pygeodesy' # PYCHOK OK # in test/bases

347 _pygeodesy_abspath_ = 'pygeodesy_abspath' # PYCHOK OK

348 _PyPy__ = _PyPy__('PyPy ') # PYCHOK + _SPACE_

349 _Python_ = _Python_('Python') # PYCHOK singleton

350 _python_ = 'python' # PYCHOK OK

351 _QUOTE1_ = "'" # PYCHOK OK

352 _QUOTE2_ = '"' # PYCHOK OK

353 _QUOTE3_ = "'''" # PYCHOK OK

354# _QUOTE6_ = '"""' # PYCHOK OK

355 _R_ = 'R' # PYCHOK OK

356 _radians_ = 'radians' # PYCHOK OK

357 _radians2_ = 'radians2' # PYCHOK SQUARED

358 _radius_ = 'radius' # PYCHOK OK

359 _radius1_ = 'radius1' # PYCHOK OK

360 _radius2_ = 'radius2' # PYCHOK OK

361 _range_ = _Range('range') # PYCHOK OK

362 _RANGLE_ = '>' # PYCHOK OK

363 _RCURLY_ = '}' # PYCHOK RBRACE

364 _reciprocal_ = 'reciprocal' # PYCHOK OK

365 _reframe_ = 'reframe' # PYCHOK OK

366 _resolution_ = 'resolution' # PYCHOK OK

367 _rIn_ = 'rIn' # PYCHOK OK

368 _RPAREN_ = ')' # PYCHOK OK

369 _RSQUARE_ = ']' # PYCHOK RBRACK

370 _s_ = 's' # PYCHOK OK

371 _S_ = 'S' # PYCHOK OK

372 _s12_ = 's12' # PYCHOK OK

373 _S12_ = 'S12' # PYCHOK OK

374 _scalar_ = 'scalar' # PYCHOK OK

375 _scale_ = 'scale' # PYCHOK OK

376 _scale0_ = 'scale0' # PYCHOK OK

377 _scipy_ = 'scipy' # PYCHOK OK

378 _semi_circular_ = 'semi-circular' # PYCHOK OK

379 _sep_ = 'sep' # PYCHOK OK

380 _singular_ = 'singular' # PYCHOK OK

381 _SLASH_ = Str_('/') # PYCHOK OK

382 _small_ = 'small' # PYCHOK OK

383 _Sphere_ = 'Sphere' # PYCHOK OK

384 _spherical_ = 'spherical' # PYCHOK OK

385 _SPACE_ = Str_(' ') # PYCHOK OK

386 _specified_ = 'specified' # PYCHOK OK

387 _STAR_ = Str_('*') # PYCHOK OK

388 _start_ = 'start' # PYCHOK OK

389 _std_ = 'std' # PYCHOK OK

390 _stdev_ = 'stdev' # PYCHOK OK

391 _tbd_ = 'tbd' # PYCHOK OK

392 _TILDE_ = '~' # PYCHOK OK

393 _to_ = 'to' # PYCHOK OK

394 _tolerance_ = _Prefix('tolerance') # PYCHOK OK

395 _too_ = _Prefix('too') # PYCHOK OK

396 _transform_ = 'transform' # PYCHOK OK

397 _UNDER_ = Str_('_') # PYCHOK OK

398 _units_ = 'units' # PYCHOK OK

399 _UNUSED_ = 'UNUSED' # PYCHOK OK

400 _up_ = 'up' # PYCHOK OK

401 _UPS_ = 'UPS' # PYCHOK OK

402 _utf_8_ = 'utf-8' # PYCHOK OK

403 _UTM_ = 'UTM' # PYCHOK OK

404 _V_ = 'V' # PYCHOK OK

405 _valid_ = 'valid' # PYCHOK OK

406 _value_ = 'value' # PYCHOK OK

407 _version_ = 'version' # PYCHOK OK

408 _vs_ = 'vs' # PYCHOK OK

409 _W_ = 'W' # PYCHOK OK

410 _WGS72_ = 'WGS72' # PYCHOK OK

411 _WGS84_ = 'WGS84' # PYCHOK OK

412 _width_ = 'width' # PYCHOK OK

413 _with_ = 'with' # PYCHOK OK

414 _x_ = 'x' # PYCHOK OK

415 _X_ = 'X' # PYCHOK OK

416 _xyz_ = 'xyz' # PYCHOK OK

417 _y_ = 'y' # PYCHOK OK

418 _Y_ = 'Y' # PYCHOK OK

419 _z_ = 'z' # PYCHOK OK

420 _Z_ = 'Z' # PYCHOK OK

421 _zone_ = 'zone' # PYCHOK OK

422

423 _EW_ = _E_ + _W_ # PYCHOK common cardinals

424 _NE_ = _N_ + _E_ # PYCHOK positive ones

425 _NS_ = _N_ + _S_ # PYCHOK OK

426 _NSEW_ = _NS_ + _EW_ # PYCHOK OK

427 _NW_ = _N_ + _W_ # PYCHOK OK

428 _SE_ = _S_ + _E_ # PYCHOK OK

429 _SW_ = _S_ + _W_ # PYCHOK negative ones

430# _NESW_ = _NE_ + _SW_ # PYCHOK clockwise

431

432 _DDOT_ = Str_(_DOT_ * 2) # PYCHOK OK

433# _DEQUAL_ = Str_(_EQUAL_ * 2) # PYCHOK OK

434# _DNL_ = Str_(_NL_ * 2) # PYCHOK OK

435 _DSLASH_ = Str_(_SLASH_ * 2) # PYCHOK OK

436 _DSTAR_ = Str_(_STAR_ * 2) # PYCHOK OK

437 _DUNDER_ = Str_(_UNDER_ * 2) # PYCHOK OK

438

439 _LR_PAIRS = {_LANGLE_: _RANGLE_,

440 _LCURLY_: _RCURLY_,

441 _LPAREN_: _RPAREN_,

442 _LSQUARE_: _RSQUARE_} # PYCHOK OK

443

444 __all__ = (_NN_, # NOT MISSING!

445 Str_.__name__) # classes

446 __version__ = '25.11.07'

447

448 if __name__ == _DMAIN_:

449

450 def _main(globalocals):

451 from pygeodesy import itemsorted, printf

452

453 t = b = 0

454 for n, v in itemsorted(globalocals, asorted=False, reverse=True):

455 if n.endswith(_UNDER_) and n.startswith(_UNDER_) and \

456 not n.startswith(_DUNDER_):

457 t += 1

458 b += len(v)

459 m = n[1:-1]

460 if m != v and m.replace(_UNDER_, _SPACE_) != v:

461 printf('%4d: %s = %r', t, n, v)

462 n = len(globalocals)

463 printf('%4d (%d) names, %s chars total, %.2f chars avg', t, n, b, float(b) / t, nl=1)

464

465 _main(globals()) # or locals()

466

467# **) MIT License

468#

469# Copyright (C) 2016-2026 -- mrJean1 at Gmail -- All Rights Reserved.

470#

471# Permission is hereby granted, free of charge, to any person obtaining a

472# copy of this software and associated documentation files (the "Software"),

473# to deal in the Software without restriction, including without limitation

474# the rights to use, copy, modify, merge, publish, distribute, sublicense,

475# and/or sell copies of the Software, and to permit persons to whom the

476# Software is furnished to do so, subject to the following conditions:

477#

478# The above copyright notice and this permission notice shall be included

479# in all copies or substantial portions of the Software.

480#

481# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

482# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

483# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL

484# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR

485# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,

486# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR

487# OTHER DEALINGS IN THE SOFTWARE.