tex, string, and separator options for units#1447
Conversation
9b88415 to
940409b
Compare
drgrice1
left a comment
There was a problem hiding this comment.
This satisfies my initial request to make the properties centralized and defined in Units.pm, but will not work for what @dpvc asked. That is so that custom units can also take advantage of the new features. For this the addUnit method will need some more modification. Also the copies of the %context::Units::Context::DISPLAY hash made on line 958 for the context::Units::Unit package and line 1442 for the context::Units::NumberWithUnit package are going to be an issue for that as well. If the addUnit method modifies the %context::Units::Context::DISPLAY hash, then the copies will not be modified appropriately. Making those copies is also not particularly efficient. Those should be references instead.
|
Note that something is also needed at line 1856 in the |
|
I'll put a pin in this (mark it as draft) until I come back from travel on July 7 (or later). I'll rework it. I can say that I did try at first to create a new One thing to think about in the meantime. I am leaning to not including the separator keys with this. This was really only included because of the degree symbol when the units are an angle. Not for anything else at present. So, like |
|
I think that the removal of the space for the degree symbol is more important to me than any of the other changes. But do what you can. I think that |
Yeah, it's complicated. I've made a version of these two files that seem to do the trick. I'm attaching them here. One of the differences is that the See what you think. |
|
I've been modifying @dpvc's files, getting close to pushing a new version for all of this. I've run into something that is an issue even before the changes happening here. The old
I believe I can handle the latter two issues. But @dpvc, do you see how to address the first one? Or maybe this is not going to work unless |
940409b to
c2ac58b
Compare
|
This is largely changes made by @dpvc in the files posted earlier in this thread. The purpose is that entries in is now
All of this has been done in a way to preserve backward compatibility with There are a few other changes.
There is also the When
|
9b5bc14 to
559096b
Compare
559096b to
7374ab0
Compare
|
A list of things I think could still be improved:
|
dpvc
left a comment
There was a problem hiding this comment.
These look like great new features that you have added. Thanks for working on that.
I make some suggested changes below, and discuss an issue with modifying the %UNITS hash, and how that is problematic for the units context, that I think needs to be addressed.
| s => { | ||
| factor => 1, | ||
| units => { s => 1 }, | ||
| prefixes => [qw(n u m)], |
There was a problem hiding this comment.
Is there a preference for qw() rather than quoted strings? It seems inconsistent to use qw() here but not in the aliases lists.
There was a problem hiding this comment.
I have developed a preference for it when there is the potential for lots of quotation marks and commas. Here with the m unit, we have qw(f p n u m c k), which would be ('f', 'p', 'n', 'u', 'm', 'c', 'k') with quotes and commas. The quotes and commas make my eyes blur and wonder if every quote is paired properly. Once I switched that one to use qw, I switched them all for a different kind of consistency.
| # For all of these units, for all of their approved prefixes, prefixed units will be added | ||
| # automatically. When the unit has aliases, then for each alias that is 3 characters or shorter, | ||
| # aliases will be added to the prefixed variant that use the prefix and that alias. Hence we will | ||
| # have unit `ns` with an alias `nsec` but not the alias `nsecond`. |
There was a problem hiding this comment.
For the longer words, I'm wondering if there should be aliases using the full prefix name, like kilometer and nanosecond. You could use a map from the single-letter prefixes to their full versions and use the correct one depending on the length of the alias. Just a thought.
There was a problem hiding this comment.
We could do that. I had an earlier version of this that did that. Actually it was doing a lot, too much I think. Each unit was tagged with a boolean for whether or not SI prefixes were appropriate. And if so, all of the SI prefixes were applied. The abbreviated prefix when the base unit was 3 characters or less. And the full prefix if longer. But that was adding all kinds of "new" things like "femtosecond". In the interest of keeping this PR from changing too much regarding what are or aren't valid units to use, I moved away from that. It leaves a few units that have always spelled out the SI prefixes: nanomol, micromol, and maybe more. Also there is the odd microN. I'm content to leave this out for now.
| for my $name (keys %UNITS) { | ||
| for my $prefix (@{ $UNITS{$name}{prefixes} }) { | ||
| if ($prefix ne 'u') { | ||
| $UNITS{"$prefix$name"} = { |
There was a problem hiding this comment.
I don't really like the idea of modifying the %UNITS hash, as it mixes the defining data with the processed data. More important, however, is that this will confuse the units context, which already handles aliases. My feeling is that you should be creating/mmodifying the %known_units has here, as that is the processed units hash.
Since the units context is already handling aliases, let it do that. But you would have to add the processing of the prefixes to the units context, as it is not currently doing that.
One reason to do that is that the units context allows addUnits() to accept new units using the format of the %UNITS hash (that probably means the documentation in the units context needs updating; there are only examples of the old-style units, so it would be good to do one for the new style; note that the old is converted to new automatically in the addUnit() method). So new units could be added that have not just aliases but also prefixes. So the units content needs to be able to handle these anyway, and it doesn't really save anything to have that processed into the %UNITS hash here. Indeed, it means that the units context will have to look through more units to find the ones that match a given fundamental unit pattern (and have to look through all the aliases for those that don't match), so there is an argument that this makes matters worse.
My suggestion does mean some duplication of code, however. Perhaps this file could provide a utility function that generates a list of alias hashes for a given unit, and then use that here and in the units context to get the aliases to be added to %known_units or into the units context. That would reduce the redundancy, and could simplify some code in the units context as well.
| }; | ||
| # if $name had short aliases, apply prefixes to those short aliases | ||
| my @short_aliases = grep { length($_) <= 3 } @{ $UNITS{$name}{aliases} }; | ||
| $UNITS{"$prefix$name"}{aliases} = [ map {"$prefix$_"} @short_aliases ] if @short_aliases; |
There was a problem hiding this comment.
I don't see where these aliases are added to the %UNITS or %known_units hashes (though they will be added in the units context, since it processes aliases itself; usually, that will be redundant given that you have added most aliases already, but not for these prefixed units).
Same for the ones at line 676.
There was a problem hiding this comment.
Well, this whole modification of %UNITS will probably be scrapped, per your previous comment. But what is happening here is that the original declaration of %UNITS had (for example) s => ... with aliases => ['sec'] and prefixes => ['n']. And this block of code adds an entirely new unit to %UNITS: ns => .... Which has aliases => ['nsec'].
At this point contextUnits.pl will do its thing with both s and ns as declared units, each with their own alias.
And also for the legacy code, aliases will be extracted for the %known_units hash.
Have you added the loadMacros("contextUnits.pl");
Context("Units")->addUnits("%");
Compute("1 %");works for me, both in the original It turns out, however, that you can't mix percentages with reals, so that Compute('1 %) == .01is false, and `` perl throws That last error needs to be fixed, and I suspect the first two want to be fixed as well. There may be situations where you do want to force the use of '%' (like "What is .01 as a percentage?"), so there may need to be a flat to control that. It looks like the But there are a number of other things that might need to be adjusted for percentages that I didn't think of earlier. For example I will think about how to address these issues, and let you know if I come up with anything. |
I'm working on that and think I have things pretty well worked out. I will post some updates as soon as they are ready.
A
I was thinking the same thing.
Well, one option would be to use |
|
First, a note that I pushed changes from your more minor comments. I agree with your more significant comments, just haven't gotten to addressing them.
I can't reproduce what I thought was happening earlier, and my best guess is that I had a typo in "dimensionless" when I tried to load that new category of units. About percents in general, if the exercise only involves percentages, then I don't feel that adding a Real to a unit (even if it is If we are in Units context, and we have Question: radians are similar, in that they are arguably dimensionless. A radian is the ratio of a certain length (an arc length in meters, say) to a radius length (also in meters). But at one point long ago radian was blessed (not in the perl sense) as one of the fundamental units. Maybe Are there other dimensionless units? permille? ppm? Which units can you multiply by |
I'm revising the description for this in the post following this post. Leaving the original here for reference.
This implements one of the suggestions from @dpvc in #1437, and replaces that pull request.
Units.pmcan havestring,tex,string_separator, andtex_separatorproperties.micronto be a named unit instead of an alias.stringproperty is used when the unit or its aliases are printed as a string.stringproperty needs to use a string that can actually be printed in hardcopy. There is a comment about this in the file above where the big units hash is defined.Compute(), make sure that any allstringproperties are also unit names.texproperty is used when the unit or its aliases are printed as tex.tex_separatorproperty are only used when the unit is not part of a larger fractional unit, and the unit is the first unit following a number. Otherwise a space is used, as has been the case. For example,180°and180° s, but180 s °(except as tex).string_separatorproperty is similar, except it is also used even when there is a larger fractional unit. For example,180°/s.degis usingtex_separatorandstring_separator, with each set to the empty string. I considered doing this withdegFanddegC, but Google tells me there should be a space for those units for scientific publications.contextUnits.plwas adding aliases forL(liter,liters,litre, andlitres). It was cleaner to move those over toUnits.pm. If there was a reason they were not already inUnits.pm, I could move them back.One thing that could still be improved, is that for string production, the spaces that are used in between numbers and units (when
string_separatoris not set), or between units and units should be nonbreaking spaces. I tried things that I though should work, but did not work for one reason or another. So that can be addressed in some future PR.Try the problem from #1437 for some basic testing. Although you may want to also try with some more complicated units that have unit products and quotients.