patternpythonMinor
Determining the least-accurately known physical constants
Viewed 0 times
determiningtheaccuratelyknownleastphysicalconstants
Problem
So, I thought I'd do this using scipy.constants:
I was reasonably pleased to be using a structured array, but it all seems a bit... obscure and unpythonic. Any suggestions?
OK... so first thing I've realised: the boolean test for constants with relative uncertainties > 0 is not necessary if I want the largest 10 values (which are all non-negative), so I can ditch that. And a few comments wouldn't go amiss:
However, pace Jeff Gohlke's comment, I'm reluctant to split up the list comprehension (which I think is a nice feature of Python). And something like
```
make_record = lambda k, v: (k,)+v+(v[2]/abs(v[0]),)
constants = np.array([make_record(k,v) for k,v in physical_constants.items()],
dtype=[('name', 'S50'), ('val', 'f8'), ('units', 'S10'),
('abs_
import numpy as np
from scipy.constants import physical_constants
constants = np.array([(k,)+v+(v[2]/abs(v[0]),) for k,v in physical_constants.items()],
dtype=[('name', 'S50'), ('val', 'f8'), ('units', 'S10'),
('abs_unc', 'f8'), ('rel_unc', 'f8')])
constants.sort(order='rel_unc')
print(constants[constants['rel_unc'] > 0][['name', 'rel_unc']][-10:])I was reasonably pleased to be using a structured array, but it all seems a bit... obscure and unpythonic. Any suggestions?
OK... so first thing I've realised: the boolean test for constants with relative uncertainties > 0 is not necessary if I want the largest 10 values (which are all non-negative), so I can ditch that. And a few comments wouldn't go amiss:
import numpy as np
from scipy.constants import physical_constants
# Create a structured array with fields for each constant's name, value, units,
# absolute uncertainty and relative uncertainty. The first of these is the key
# in the physical_constants dictionary; the next three are stored in a tuple
# as the corresponding value. Calculate the final field entry, the relative
# uncertainty from the absolute uncertainty and the absolute value of the
# constant.
constants = np.array([(k,)+v+(v[2]/abs(v[0]),)
for k,v in physical_constants.items()],
dtype=[('name', 'S50'), ('val', 'f8'), ('units', 'S10'),
('abs_unc', 'f8'), ('rel_unc', 'f8')])
constants.sort(order='rel_unc')
print(constants[['name', 'rel_unc']][-10:])However, pace Jeff Gohlke's comment, I'm reluctant to split up the list comprehension (which I think is a nice feature of Python). And something like
```
make_record = lambda k, v: (k,)+v+(v[2]/abs(v[0]),)
constants = np.array([make_record(k,v) for k,v in physical_constants.items()],
dtype=[('name', 'S50'), ('val', 'f8'), ('units', 'S10'),
('abs_
Solution
I think the biggest problem here is that you're trying to do too much in a single line. It seems obscure because it is obscure. If I were looking at this outside of a Code Review setting, I would think that someone had purposefully obfuscated it or condensed it for some character count restriction.
Consider breaking apart your lines in order to make your code more legible. Whoever looks over or has to maintain your code in the future (even if it's just you) will be incredibly grateful for it.
I was going to try and break this down into a legitimate block of code, but I have absolutely no idea what your various variables are supposed to represent. What does the
You're doing like four things here. You're comparing to produce a
I can't even begin to trace out what you're trying to do in your first line of code, unfortunately, or I would.
I have a story which demonstrates the point. On one of my more recent projects at work, a contractor had produced some code with several nested ternary conditions. It looked something like this, in one line of JavaScript:
It took me awhile to figure out exactly what he was trying to accomplish. When I asked him about it later, he said he thought he was being very clever and doing something good for the code by being "short and succinct".
But it's not clever, and it's far from helpful. It's just frustrating for the people who have to maintain your code later.
Consider breaking apart your lines in order to make your code more legible. Whoever looks over or has to maintain your code in the future (even if it's just you) will be incredibly grateful for it.
I was going to try and break this down into a legitimate block of code, but I have absolutely no idea what your various variables are supposed to represent. What does the
v list hold (e.g., what is v[0]? what is v[2]?). But let's take your last line of code, which is at least somewhat comprehensible:print(constants[constants['rel_unc'] > 0][['name', 'rel_unc']][-10:])You're doing like four things here. You're comparing to produce a
bool, extracting an element of a list, performing a string slice operation, and printing a value. Again, it seems obscure because it is obscure.I can't even begin to trace out what you're trying to do in your first line of code, unfortunately, or I would.
I have a story which demonstrates the point. On one of my more recent projects at work, a contractor had produced some code with several nested ternary conditions. It looked something like this, in one line of JavaScript:
var_1 ? long_complex_variable_1 : var_2 ? long_complex_variable_2 :
var_3 === var_4 ? (var_5 ? long_complex_variable_3 : long_complex_variable_4) :
long_complex_variable_5It took me awhile to figure out exactly what he was trying to accomplish. When I asked him about it later, he said he thought he was being very clever and doing something good for the code by being "short and succinct".
But it's not clever, and it's far from helpful. It's just frustrating for the people who have to maintain your code later.
Code Snippets
print(constants[constants['rel_unc'] > 0][['name', 'rel_unc']][-10:])var_1 ? long_complex_variable_1 : var_2 ? long_complex_variable_2 :
var_3 === var_4 ? (var_5 ? long_complex_variable_3 : long_complex_variable_4) :
long_complex_variable_5Context
StackExchange Code Review Q#47496, answer score: 3
Revisions (0)
No revisions yet.