summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrien Hopkins <ahopk127@my.yorku.ca>2021-08-26 15:09:23 -0400
committerAdrien Hopkins <ahopk127@my.yorku.ca>2021-08-26 15:09:23 -0400
commit816f744169d1ecdb689aba27cb396ab452fdc3fe (patch)
tree1eed1edbbf6f3131dfb6a26c1480d023e44f6c51
parent236b497f516694929b9fe409508a7cce21ca9e6e (diff)
parent75a5a1a2a40b0eb4361d6fc046eb8918ef6f5292 (diff)
Merge branch 'new-documentation-0.3.1' into develop
-rw-r--r--.classpath7
-rw-r--r--CHANGELOG.org4
-rw-r--r--README.org543
-rw-r--r--docs/design.org82
-rw-r--r--docs/design.pdfbin0 -> 242954 bytes
-rw-r--r--docs/design.tex135
-rw-r--r--docs/diagrams/units-class-diagram.plantuml.pngbin0 -> 94248 bytes
-rw-r--r--docs/diagrams/units-class-diagram.plantuml.txt72
-rw-r--r--docs/manual.org83
-rw-r--r--docs/manual.pdfbin0 -> 172013 bytes
-rw-r--r--docs/manual.tex143
-rw-r--r--screenshots/main-interface-dimension-converter.pngbin0 -> 11281 bytes
-rw-r--r--screenshots/main-interface-expression-converter.pngbin0 -> 8780 bytes
-rw-r--r--screenshots/main-interface-settings.pngbin0 -> 25953 bytes
-rw-r--r--screenshots/sample-conversion-dimension-converter.pngbin0 -> 12279 bytes
-rw-r--r--screenshots/sample-conversion-results-dimension-converter.pngbin0 -> 13400 bytes
-rw-r--r--screenshots/sample-conversion-results-expression-converter.pngbin0 -> 10892 bytes
-rw-r--r--src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java12
-rw-r--r--src/main/java/sevenUnits/converterGUI/SevenUnitsGUI.java36
-rw-r--r--src/main/java/sevenUnits/unit/BaseUnit.java2
-rw-r--r--src/main/java/sevenUnits/unit/BritishImperial.java22
-rw-r--r--src/main/java/sevenUnits/unit/FunctionalUnit.java2
-rw-r--r--src/main/java/sevenUnits/unit/FunctionalUnitlike.java2
-rw-r--r--src/main/java/sevenUnits/unit/LinearUnit.java6
-rw-r--r--src/main/java/sevenUnits/unit/LinearUnitValue.java6
-rw-r--r--src/main/java/sevenUnits/unit/Metric.java (renamed from src/main/java/sevenUnits/unit/SI.java)88
-rw-r--r--src/main/java/sevenUnits/unit/MultiUnit.java2
-rw-r--r--src/main/java/sevenUnits/unit/USCustomary.java8
-rw-r--r--src/main/java/sevenUnits/unit/Unit.java38
-rw-r--r--src/main/java/sevenUnits/unit/UnitDatabase.java18
-rw-r--r--src/main/java/sevenUnits/unit/UnitPrefix.java2
-rw-r--r--src/main/java/sevenUnits/unit/Unitlike.java2
-rw-r--r--src/main/java/sevenUnits/utils/ConditionalExistenceCollections.java (renamed from src/main/java/sevenUnits/math/ConditionalExistenceCollections.java)2
-rw-r--r--src/main/java/sevenUnits/utils/DecimalComparison.java (renamed from src/main/java/sevenUnits/math/DecimalComparison.java)2
-rw-r--r--src/main/java/sevenUnits/utils/ExpressionParser.java (renamed from src/main/java/sevenUnits/math/ExpressionParser.java)2
-rw-r--r--src/main/java/sevenUnits/utils/ObjectProduct.java (renamed from src/main/java/sevenUnits/math/ObjectProduct.java)2
-rw-r--r--src/main/java/sevenUnits/utils/UncertainDouble.java (renamed from src/main/java/sevenUnits/math/UncertainDouble.java)2
-rw-r--r--src/main/java/sevenUnits/utils/package-info.java (renamed from src/main/java/sevenUnits/math/package-info.java)7
-rw-r--r--src/test/java/sevenUnits/unit/MultiUnitTest.java6
-rw-r--r--src/test/java/sevenUnits/unit/UnitDatabaseTest.java16
-rw-r--r--src/test/java/sevenUnits/unit/UnitTest.java52
-rw-r--r--src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java (renamed from src/test/java/sevenUnits/math/ConditionalExistenceCollectionsTest.java)6
-rw-r--r--src/test/java/sevenUnits/utils/ExpressionParserTest.java (renamed from src/test/java/sevenUnits/math/ExpressionParserTest.java)6
-rw-r--r--src/test/java/sevenUnits/utils/ObjectProductTest.java (renamed from src/test/java/sevenUnits/math/ObjectProductTest.java)26
44 files changed, 720 insertions, 724 deletions
diff --git a/.classpath b/.classpath
index 66f8050..79126ac 100644
--- a/.classpath
+++ b/.classpath
@@ -19,13 +19,6 @@
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
- <classpathentry kind="src" output="bin/test" path="src/test/resources">
- <attributes>
- <attribute name="gradle_scope" value="test"/>
- <attribute name="gradle_used_by_scope" value="test"/>
- <attribute name="test" value="true"/>
- </attributes>
- </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
diff --git a/CHANGELOG.org b/CHANGELOG.org
index f72e01a..5fb3641 100644
--- a/CHANGELOG.org
+++ b/CHANGELOG.org
@@ -1,8 +1,12 @@
* Changelog
All notable changes in this project will be shown in this file.
** Unreleased
+*** Added
+ - Created a user manual
+ - Create a design document (a document detailing the program's design for programmer use)
*** Changed
- Changed the name of the project from "Unit Converter" to "7Units"
+ - Tweaked the README, removing content that belongs in the new user manual
** v0.3.0 - [2021-06-12 Sat]
*** Added
- Added a simple unit conversion method to the Unit interface
diff --git a/README.org b/README.org
index ad4651a..0aa4dcf 100644
--- a/README.org
+++ b/README.org
@@ -1,531 +1,18 @@
* 7Units v0.3.0
-(this project uses Semantic Versioning)
+ (this project uses Semantic Versioning)
** What is it?
- This is a unit converter, which allows you to convert between different units, and includes a GUI which can read unit data from a file (using some unit math) and convert between units that you type in, and has a unit and prefix viewer to check the units that have been loaded in.
-** Features
- - Convert between units and expressions of units
- - linear or base units can use unit prefixes (including non-metric units!)
- - and prefixes are defined in an editable data file, in a simple and intuitive format.
- - Viewer and Prefix Viewer which allow you to search through all of the available units and prefixes and learn details about them.
- - All of SI included in default text file
- - Choose your precision
-** How to Convert (in "Convert Units")
-To convert units, simply:
- 1. Select the kind of units to convert (length/mass/time, etc.).
- 2. Select the units to convert from and to (you can use the text boxes above to search)
- 3. Enter a value to convert
- 4. Press "Convert"
-** How to Convert (in "Convert Expressions")
-To convert units, simply enter the first unit in the From box and the second unit in the To box. Press Convert and a result will appear in the output box. Both boxes accept unit expressions, so you can input things like ‘1.7 m’, ‘85 km/h’ and ‘35 A * 14 s’ into either box.
-
-*Warning*: The space between the number and the unit name is required, or else the whole expression will be interpreted as a unit name. Spaces are not required for operators.
-
-Use the slider at the bottom to choose the maximum precision of the result, in significant digits, not decimal places.
-** Units Files and Expressions
-As mentioned previously, all units are loaded from a units file. The format for lines consists of a name for the unit, some tabs (not spaces), and an expression. The following operations are supported in expressions:
- - Addition using the plus sign (+), which only works on compatible units
- - Subtraction using the minus sign (-), which only works on compatible units
- - Multiplication using spaces ( ) or asterisks (*)
- - Division using the forward slash (/)
- - Exponentiation using the caret (^)
- - Brackets to manipulate order of operations
-Every argument can be either a linear unit, a base unit or a number, except exponents which must be integers.
-
-Example:
-
-inch 25.4 mm # Define ‘inch’ as equal to the product of 25.4 and ‘mm’
-
-mph mile / hour # Define ‘mph’ as equal to the quotient of ‘mile’ and ‘hour’
-
-litre 0.001 m^3 # Define ‘litre’ as equal to the product of 0.001 and the unit ‘m’ raised to the exponent 3
-
-Anything after a number sign (#) and blank lines will be ignored.
-
-Unit prefixes are defined differently. When a unit name ends with the dash (-) character, it is interpreted as a prefix. Prefix expressions are not as powerful as unit expressions, they can only do:
- - Multiplication using spaces ( ) or asterisks (*)
- - Division using the forward slash (/)
- - Exponentiation using the caret (^)
-Every argument can be a number or a prefix name, except exponents which much be integers
-** Unit Prefixes
-In SI, you can have a unit prefix, which you attach to the start of a unit and it multiplies the unit by a certain value. For example, milli-metre = 0.001 * metre. This unit converter supports unit prefixes, and you can put any number of prefixes before a linear or base unit to transform it (this includes non-SI units).
-You can use more than one prefix at once (yottayottametre = really really long distance), but you may not convert prefixes alone. If you want to do that, use ‘unit’ or ‘u’ (ku = 1000000 mu). You can also use u for converting from numbers (pi = 3.141593 u).
-
-The default unit file allows you to use D-, H- and K- in place of da-, h- and k- if you want.
-
-*Warning*: The standard prefixes will never use 1024 instead of 1000, even when operating on bits and bytes. Use ‘Ki’, ‘Mi’, ‘Gi’, ‘Ti’ and so on instead.
-** Nonlinear Units
-Sometimes, units cannot be converted from and to by simply multiplying and dividing. A common example of this is the Celsius and Fahrenheit temperature scales, which require multiplication and addition to convert to each other (and to their base, Kelvin).
-
-To use nonlinear units, use the following syntax:
-FROM: unit1(value)
-TO: unit2
-
-Nonlinear units cannot:
- - add, subtract, multiply, divide or exponentiate
- - use prefixes
- - be defined by unit files
-
-To define a nonlinear unit, make an anonymous inner type (or any other subclass) of Unit, and define the conversion methods. You can do this easily using Unit's static methods.
-** Unit and Prefix Viewers
-The unit and prefix viewers can be used to see the available units (without prefixes) and prefixes. Upon opening them, you will see a list of units or prefixes on your left. Using the text box above, the list can be filtered. When a unit is clicked on, details about will be displayed on the right.
-** Copyright and Licences
-The Unit Converter program is Copyright (C) 2018-2021 Adrien Hopkins. It is released under the terms of the Aferro GNU General Public License, version 3.0 or any later version published by the Free Software Foundation. A copy of this license should be provided with this program, and a human-readable summary of the very similar GNU General Public License can be found at the following link: https://www.gnu.org/licenses/quick-guide-gplv3.html, although this summary is NOT a replacement for the actual license.
-
-This document is Copyright (C) 2019 Adrien Hopkins. This document is dual-licensed under the terms of the GNU Free Documentation License and the Creative Commons Attribution-ShareAlike License. More details are in the next paragraphs:
-
-Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled "GNU Free Documentation License".
-
-This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License. To view a copy of this license, visit https://creativecommons.org/licenses/by-sa/4.0/ or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA.
-*** GNU Free Documentation License
-
- GNU Free Documentation License
- Version 1.3, 3 November 2008
-
-
- Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
- <https://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-0. PREAMBLE
-
-The purpose of this License is to make a manual, textbook, or other
-functional and useful document "free" in the sense of freedom: to
-assure everyone the effective freedom to copy and redistribute it,
-with or without modifying it, either commercially or noncommercially.
-Secondarily, this License preserves for the author and publisher a way
-to get credit for their work, while not being considered responsible
-for modifications made by others.
-
-This License is a kind of "copyleft", which means that derivative
-works of the document must themselves be free in the same sense. It
-complements the GNU General Public License, which is a copyleft
-license designed for free software.
-
-We have designed this License in order to use it for manuals for free
-software, because free software needs free documentation: a free
-program should come with manuals providing the same freedoms that the
-software does. But this License is not limited to software manuals;
-it can be used for any textual work, regardless of subject matter or
-whether it is published as a printed book. We recommend this License
-principally for works whose purpose is instruction or reference.
-
-
-1. APPLICABILITY AND DEFINITIONS
-
-This License applies to any manual or other work, in any medium, that
-contains a notice placed by the copyright holder saying it can be
-distributed under the terms of this License. Such a notice grants a
-world-wide, royalty-free license, unlimited in duration, to use that
-work under the conditions stated herein. The "Document", below,
-refers to any such manual or work. Any member of the public is a
-licensee, and is addressed as "you". You accept the license if you
-copy, modify or distribute the work in a way requiring permission
-under copyright law.
-
-A "Modified Version" of the Document means any work containing the
-Document or a portion of it, either copied verbatim, or with
-modifications and/or translated into another language.
-
-A "Secondary Section" is a named appendix or a front-matter section of
-the Document that deals exclusively with the relationship of the
-publishers or authors of the Document to the Document's overall
-subject (or to related matters) and contains nothing that could fall
-directly within that overall subject. (Thus, if the Document is in
-part a textbook of mathematics, a Secondary Section may not explain
-any mathematics.) The relationship could be a matter of historical
-connection with the subject or with related matters, or of legal,
-commercial, philosophical, ethical or political position regarding
-them.
-
-The "Invariant Sections" are certain Secondary Sections whose titles
-are designated, as being those of Invariant Sections, in the notice
-that says that the Document is released under this License. If a
-section does not fit the above definition of Secondary then it is not
-allowed to be designated as Invariant. The Document may contain zero
-Invariant Sections. If the Document does not identify any Invariant
-Sections then there are none.
-
-The "Cover Texts" are certain short passages of text that are listed,
-as Front-Cover Texts or Back-Cover Texts, in the notice that says that
-the Document is released under this License. A Front-Cover Text may
-be at most 5 words, and a Back-Cover Text may be at most 25 words.
-
-A "Transparent" copy of the Document means a machine-readable copy,
-represented in a format whose specification is available to the
-general public, that is suitable for revising the document
-straightforwardly with generic text editors or (for images composed of
-pixels) generic paint programs or (for drawings) some widely available
-drawing editor, and that is suitable for input to text formatters or
-for automatic translation to a variety of formats suitable for input
-to text formatters. A copy made in an otherwise Transparent file
-format whose markup, or absence of markup, has been arranged to thwart
-or discourage subsequent modification by readers is not Transparent.
-An image format is not Transparent if used for any substantial amount
-of text. A copy that is not "Transparent" is called "Opaque".
-
-Examples of suitable formats for Transparent copies include plain
-ASCII without markup, Texinfo input format, LaTeX input format, SGML
-or XML using a publicly available DTD, and standard-conforming simple
-HTML, PostScript or PDF designed for human modification. Examples of
-transparent image formats include PNG, XCF and JPG. Opaque formats
-include proprietary formats that can be read and edited only by
-proprietary word processors, SGML or XML for which the DTD and/or
-processing tools are not generally available, and the
-machine-generated HTML, PostScript or PDF produced by some word
-processors for output purposes only.
-
-The "Title Page" means, for a printed book, the title page itself,
-plus such following pages as are needed to hold, legibly, the material
-this License requires to appear in the title page. For works in
-formats which do not have any title page as such, "Title Page" means
-the text near the most prominent appearance of the work's title,
-preceding the beginning of the body of the text.
-
-The "publisher" means any person or entity that distributes copies of
-the Document to the public.
-
-A section "Entitled XYZ" means a named subunit of the Document whose
-title either is precisely XYZ or contains XYZ in parentheses following
-text that translates XYZ in another language. (Here XYZ stands for a
-specific section name mentioned below, such as "Acknowledgements",
-"Dedications", "Endorsements", or "History".) To "Preserve the Title"
-of such a section when you modify the Document means that it remains a
-section "Entitled XYZ" according to this definition.
-
-The Document may include Warranty Disclaimers next to the notice which
-states that this License applies to the Document. These Warranty
-Disclaimers are considered to be included by reference in this
-License, but only as regards disclaiming warranties: any other
-implication that these Warranty Disclaimers may have is void and has
-no effect on the meaning of this License.
-
-2. VERBATIM COPYING
-
-You may copy and distribute the Document in any medium, either
-commercially or noncommercially, provided that this License, the
-copyright notices, and the license notice saying this License applies
-to the Document are reproduced in all copies, and that you add no
-other conditions whatsoever to those of this License. You may not use
-technical measures to obstruct or control the reading or further
-copying of the copies you make or distribute. However, you may accept
-compensation in exchange for copies. If you distribute a large enough
-number of copies you must also follow the conditions in section 3.
-
-You may also lend copies, under the same conditions stated above, and
-you may publicly display copies.
-
-
-3. COPYING IN QUANTITY
-
-If you publish printed copies (or copies in media that commonly have
-printed covers) of the Document, numbering more than 100, and the
-Document's license notice requires Cover Texts, you must enclose the
-copies in covers that carry, clearly and legibly, all these Cover
-Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
-the back cover. Both covers must also clearly and legibly identify
-you as the publisher of these copies. The front cover must present
-the full title with all words of the title equally prominent and
-visible. You may add other material on the covers in addition.
-Copying with changes limited to the covers, as long as they preserve
-the title of the Document and satisfy these conditions, can be treated
-as verbatim copying in other respects.
-
-If the required texts for either cover are too voluminous to fit
-legibly, you should put the first ones listed (as many as fit
-reasonably) on the actual cover, and continue the rest onto adjacent
-pages.
-
-If you publish or distribute Opaque copies of the Document numbering
-more than 100, you must either include a machine-readable Transparent
-copy along with each Opaque copy, or state in or with each Opaque copy
-a computer-network location from which the general network-using
-public has access to download using public-standard network protocols
-a complete Transparent copy of the Document, free of added material.
-If you use the latter option, you must take reasonably prudent steps,
-when you begin distribution of Opaque copies in quantity, to ensure
-that this Transparent copy will remain thus accessible at the stated
-location until at least one year after the last time you distribute an
-Opaque copy (directly or through your agents or retailers) of that
-edition to the public.
-
-It is requested, but not required, that you contact the authors of the
-Document well before redistributing any large number of copies, to
-give them a chance to provide you with an updated version of the
-Document.
-
-
-4. MODIFICATIONS
-
-You may copy and distribute a Modified Version of the Document under
-the conditions of sections 2 and 3 above, provided that you release
-the Modified Version under precisely this License, with the Modified
-Version filling the role of the Document, thus licensing distribution
-and modification of the Modified Version to whoever possesses a copy
-of it. In addition, you must do these things in the Modified Version:
-
-A. Use in the Title Page (and on the covers, if any) a title distinct
- from that of the Document, and from those of previous versions
- (which should, if there were any, be listed in the History section
- of the Document). You may use the same title as a previous version
- if the original publisher of that version gives permission.
-B. List on the Title Page, as authors, one or more persons or entities
- responsible for authorship of the modifications in the Modified
- Version, together with at least five of the principal authors of the
- Document (all of its principal authors, if it has fewer than five),
- unless they release you from this requirement.
-C. State on the Title page the name of the publisher of the
- Modified Version, as the publisher.
-D. Preserve all the copyright notices of the Document.
-E. Add an appropriate copyright notice for your modifications
- adjacent to the other copyright notices.
-F. Include, immediately after the copyright notices, a license notice
- giving the public permission to use the Modified Version under the
- terms of this License, in the form shown in the Addendum below.
-G. Preserve in that license notice the full lists of Invariant Sections
- and required Cover Texts given in the Document's license notice.
-H. Include an unaltered copy of this License.
-I. Preserve the section Entitled "History", Preserve its Title, and add
- to it an item stating at least the title, year, new authors, and
- publisher of the Modified Version as given on the Title Page. If
- there is no section Entitled "History" in the Document, create one
- stating the title, year, authors, and publisher of the Document as
- given on its Title Page, then add an item describing the Modified
- Version as stated in the previous sentence.
-J. Preserve the network location, if any, given in the Document for
- public access to a Transparent copy of the Document, and likewise
- the network locations given in the Document for previous versions
- it was based on. These may be placed in the "History" section.
- You may omit a network location for a work that was published at
- least four years before the Document itself, or if the original
- publisher of the version it refers to gives permission.
-K. For any section Entitled "Acknowledgements" or "Dedications",
- Preserve the Title of the section, and preserve in the section all
- the substance and tone of each of the contributor acknowledgements
- and/or dedications given therein.
-L. Preserve all the Invariant Sections of the Document,
- unaltered in their text and in their titles. Section numbers
- or the equivalent are not considered part of the section titles.
-M. Delete any section Entitled "Endorsements". Such a section
- may not be included in the Modified Version.
-N. Do not retitle any existing section to be Entitled "Endorsements"
- or to conflict in title with any Invariant Section.
-O. Preserve any Warranty Disclaimers.
-
-If the Modified Version includes new front-matter sections or
-appendices that qualify as Secondary Sections and contain no material
-copied from the Document, you may at your option designate some or all
-of these sections as invariant. To do this, add their titles to the
-list of Invariant Sections in the Modified Version's license notice.
-These titles must be distinct from any other section titles.
-
-You may add a section Entitled "Endorsements", provided it contains
-nothing but endorsements of your Modified Version by various
-parties--for example, statements of peer review or that the text has
-been approved by an organization as the authoritative definition of a
-standard.
-
-You may add a passage of up to five words as a Front-Cover Text, and a
-passage of up to 25 words as a Back-Cover Text, to the end of the list
-of Cover Texts in the Modified Version. Only one passage of
-Front-Cover Text and one of Back-Cover Text may be added by (or
-through arrangements made by) any one entity. If the Document already
-includes a cover text for the same cover, previously added by you or
-by arrangement made by the same entity you are acting on behalf of,
-you may not add another; but you may replace the old one, on explicit
-permission from the previous publisher that added the old one.
-
-The author(s) and publisher(s) of the Document do not by this License
-give permission to use their names for publicity for or to assert or
-imply endorsement of any Modified Version.
-
-
-5. COMBINING DOCUMENTS
-
-You may combine the Document with other documents released under this
-License, under the terms defined in section 4 above for modified
-versions, provided that you include in the combination all of the
-Invariant Sections of all of the original documents, unmodified, and
-list them all as Invariant Sections of your combined work in its
-license notice, and that you preserve all their Warranty Disclaimers.
-
-The combined work need only contain one copy of this License, and
-multiple identical Invariant Sections may be replaced with a single
-copy. If there are multiple Invariant Sections with the same name but
-different contents, make the title of each such section unique by
-adding at the end of it, in parentheses, the name of the original
-author or publisher of that section if known, or else a unique number.
-Make the same adjustment to the section titles in the list of
-Invariant Sections in the license notice of the combined work.
-
-In the combination, you must combine any sections Entitled "History"
-in the various original documents, forming one section Entitled
-"History"; likewise combine any sections Entitled "Acknowledgements",
-and any sections Entitled "Dedications". You must delete all sections
-Entitled "Endorsements".
-
-
-6. COLLECTIONS OF DOCUMENTS
-
-You may make a collection consisting of the Document and other
-documents released under this License, and replace the individual
-copies of this License in the various documents with a single copy
-that is included in the collection, provided that you follow the rules
-of this License for verbatim copying of each of the documents in all
-other respects.
-
-You may extract a single document from such a collection, and
-distribute it individually under this License, provided you insert a
-copy of this License into the extracted document, and follow this
-License in all other respects regarding verbatim copying of that
-document.
-
-
-7. AGGREGATION WITH INDEPENDENT WORKS
-
-A compilation of the Document or its derivatives with other separate
-and independent documents or works, in or on a volume of a storage or
-distribution medium, is called an "aggregate" if the copyright
-resulting from the compilation is not used to limit the legal rights
-of the compilation's users beyond what the individual works permit.
-When the Document is included in an aggregate, this License does not
-apply to the other works in the aggregate which are not themselves
-derivative works of the Document.
-
-If the Cover Text requirement of section 3 is applicable to these
-copies of the Document, then if the Document is less than one half of
-the entire aggregate, the Document's Cover Texts may be placed on
-covers that bracket the Document within the aggregate, or the
-electronic equivalent of covers if the Document is in electronic form.
-Otherwise they must appear on printed covers that bracket the whole
-aggregate.
-
-
-8. TRANSLATION
-
-Translation is considered a kind of modification, so you may
-distribute translations of the Document under the terms of section 4.
-Replacing Invariant Sections with translations requires special
-permission from their copyright holders, but you may include
-translations of some or all Invariant Sections in addition to the
-original versions of these Invariant Sections. You may include a
-translation of this License, and all the license notices in the
-Document, and any Warranty Disclaimers, provided that you also include
-the original English version of this License and the original versions
-of those notices and disclaimers. In case of a disagreement between
-the translation and the original version of this License or a notice
-or disclaimer, the original version will prevail.
-
-If a section in the Document is Entitled "Acknowledgements",
-"Dedications", or "History", the requirement (section 4) to Preserve
-its Title (section 1) will typically require changing the actual
-title.
-
-
-9. TERMINATION
-
-You may not copy, modify, sublicense, or distribute the Document
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense, or distribute it is void, and
-will automatically terminate your rights under this License.
-
-However, if you cease all violation of this License, then your license
-from a particular copyright holder is reinstated (a) provisionally,
-unless and until the copyright holder explicitly and finally
-terminates your license, and (b) permanently, if the copyright holder
-fails to notify you of the violation by some reasonable means prior to
-60 days after the cessation.
-
-Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License. If your rights have been terminated and not permanently
-reinstated, receipt of a copy of some or all of the same material does
-not give you any rights to use it.
-
-
-10. FUTURE REVISIONS OF THIS LICENSE
-
-The Free Software Foundation may publish new, revised versions of the
-GNU Free Documentation License from time to time. Such new versions
-will be similar in spirit to the present version, but may differ in
-detail to address new problems or concerns. See
-https://www.gnu.org/licenses/.
-
-Each version of the License is given a distinguishing version number.
-If the Document specifies that a particular numbered version of this
-License "or any later version" applies to it, you have the option of
-following the terms and conditions either of that specified version or
-of any later version that has been published (not as a draft) by the
-Free Software Foundation. If the Document does not specify a version
-number of this License, you may choose any version ever published (not
-as a draft) by the Free Software Foundation. If the Document
-specifies that a proxy can decide which future versions of this
-License can be used, that proxy's public statement of acceptance of a
-version permanently authorizes you to choose that version for the
-Document.
-
-11. RELICENSING
-
-"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
-World Wide Web server that publishes copyrightable works and also
-provides prominent facilities for anybody to edit those works. A
-public wiki that anybody can edit is an example of such a server. A
-"Massive Multiauthor Collaboration" (or "MMC") contained in the site
-means any set of copyrightable works thus published on the MMC site.
-
-"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
-license published by Creative Commons Corporation, a not-for-profit
-corporation with a principal place of business in San Francisco,
-California, as well as future copyleft versions of that license
-published by that same organization.
-
-"Incorporate" means to publish or republish a Document, in whole or in
-part, as part of another Document.
-
-An MMC is "eligible for relicensing" if it is licensed under this
-License, and if all works that were first published under this License
-somewhere other than this MMC, and subsequently incorporated in whole or
-in part into the MMC, (1) had no cover texts or invariant sections, and
-(2) were thus incorporated prior to November 1, 2008.
-
-The operator of an MMC Site may republish an MMC contained in the site
-under CC-BY-SA on the same site at any time before August 1, 2009,
-provided the MMC is eligible for relicensing.
-
-
-ADDENDUM: How to use this License for your documents
-
-To use this License in a document you have written, include a copy of
-the License in the document and put the following copyright and
-license notices just after the title page:
-
- Copyright (c) YEAR YOUR NAME.
- Permission is granted to copy, distribute and/or modify this document
- under the terms of the GNU Free Documentation License, Version 1.3
- or any later version published by the Free Software Foundation;
- with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
- A copy of the license is included in the section entitled "GNU
- Free Documentation License".
-
-If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
-replace the "with...Texts." line with this:
-
- with the Invariant Sections being LIST THEIR TITLES, with the
- Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
-
-If you have Invariant Sections without Cover Texts, or some other
-combination of the three, merge those two alternatives to suit the
-situation.
-
-If your document contains nontrivial examples of program code, we
-recommend releasing these examples in parallel under your choice of
-free software license, such as the GNU General Public License,
-to permit their use in free software.
+ This is a unit converter, which allows you to convert between different units, and includes a GUI which can read unit data from a file (using some unit math) and convert between units that you type in, and has a unit and prefix viewer to check the units that have been loaded in.
+ Check the [[./docs/manual.pdf][user manual]] for information on how to use the program.
+** Features
+ - Convert between units and between expressions of units
+ - Any linear or base units can use unit prefixes (including non-metric units!)
+ - Units and prefixes are defined in an editable data file, in a simple and intuitive format.
+ - Viewer and Prefix Viewer which allow you to search through all of the available units and prefixes and learn details about them.
+ - All of SI included in default text file
+ - Customizable rounding rules
+** Screenshots
+ #+CAPTION: The main conversion interface
+ [[./screenshots/main-interface-dimension-converter.png]]
+ #+CAPTION: A secondary, more complicated conversion option
+ [[./screenshots/main-interface-expression-converter.png]]
diff --git a/docs/design.org b/docs/design.org
new file mode 100644
index 0000000..be345f2
--- /dev/null
+++ b/docs/design.org
@@ -0,0 +1,82 @@
+#+TITLE: 7Units Design Document
+#+SUBTITLE: For version 0.3.1
+#+DATE: 2021 August 26
+#+LaTeX_HEADER: \usepackage[a4paper, lmargin=25mm, rmargin=25mm, tmargin=25mm, bmargin=25mm]{geometry}
+#+LaTeX_HEADER: \usepackage{xurl}
+#+LaTeX: \newpage
+
+* Introduction
+ 7Units is a program that can convert between units. This document details the internal design of 7Units, intended to be used by current and future developers.
+
+ The frontend code is currently subject to change, so it is not included in the current version of this document.
+* Unit System Design
+ Any code related to the backend unit system is stored in the ~sevenUnits.unit~ package.
+
+ Here is a class diagram of the system. Unimportant methods, methods inherited from Object, getters and setters have been omitted.
+ [[./diagrams/units-class-diagram.plantuml.png]]
+ #+CAPTION: Class diagram of sevenUnits.unit
+ #+LaTeX: \newpage
+** Dimensions
+ Dimensions represent what a unit is measuring, such as length, time, or energy. Dimensions are represented as an [[*ObjectProduct][ObjectProduct]]<BaseDimension>, where ~BaseDimension~ is a very simple class (its only properties are a name and a symbol) which represents the dimension of a base unit; these base dimensions can be multiplied to create all other Dimensions.
+** Unit Classes
+ Units are internally represented by the abstract class ~Unit~. All units have an [[*ObjectProduct][ObjectProduct]]<BaseUnit> (referred to as the base) that they are based on, a dimension (ObjectProduct<BaseDimension>), one or more names and a symbol (these last two bits of data are contained in the ~NameSymbol~ class). The dimension is calculated from the base unit when needed; the variable is just a cache. It has two constructors: a package-private one used to make ~BaseUnit~ instances, and a protected one used to make general units (for other subclasses of ~Unit~). All unit classes are immutable.
+
+ Units also have two conversion functions - one which converts from a value expressed in this unit to its base unit, and another which converts from a value expressed in the base unit to this unit. In ~Unit~, they are defined as two abstract methods. This allows you to convert from any unit to any other (as long as they have the same base, i.e. you aren't converting metres to pounds). To convert from A to B, first convert from A to its base, then convert from the base to B.
+
+ ~BaseUnit~ represents a unit that all other units are defined by. All of the units used by this system are defined by seven SI ~BaseUnit~ instances (metre, second, kilogram, ampere, kelvin, mole, candela; this is what 7Units is named after) and two non-SI ~BaseUnit~ instances (US dollar and bit). Because base units are themselves units (and should be able to be used as units), ~BaseUnit~ is a subclass of ~Unit~, using its own package-private constructor.
+
+ However, most units are instances of ~LinearUnit~, another subclass of ~Unit~. ~LinearUnit~ represents a unit that is /a product of a base unit and a constant called the *conversion factor*/. Most units you've ever used fall under this definition, the only common exceptions are degrees Celsius and Fahrenheit. This simplicity allows the ~LinearUnit~ to do many things:
+ - It can implement conversion to and from the base as multiplying and dividing by the conversion factor respectively
+ - You can easily create new units by multiplying or dividing a ~LinearUnit~ by a number (for example, kilometre = metre * 1000). This can be easily implemented as multiplying this unit's conversion factor by the multiplier and returning a new ~LinearUnit~ with that conversion factor factor.
+ - You can add or subtract two ~LinearUnit~ instances to create a third (as long as they have the same base) by adding or subtracting the conversion factor.
+ - You can multiply or divide any two ~LinearUnit~ instances to create a third by multiplying or dividing the bases and conversion factors.
+ - Note that any operations will return a unit without name(s) or a symbol. All unit classes have a ~withName~ method that returns a copy of them with different names and/or a different symbol (all of this info is contained in the ~NameSymbol~ class)
+
+ There are a few more classes which play small roles in the unit system:
+ - Unitlike :: A class that is like a unit, but its "value" can be any class. The only use of this class right now is to implement ~MultiUnit~, a combination of units (like "foot + inch", commonly used in North America for measuring height); its "value" is a list of numbers.
+ - FunctionalUnit :: A convenience class that implements the two conversion functions of ~Unit~ using ~DoubleUnaryOperator~ instances. This is used internally to implement degrees Celsius and Fahrenheit. There is also a version of this for ~Unitlike~, ~FunctionalUnitlike~.
+ - UnitValue :: A value expressed as a certain unit (such as "7 inches"). This class is used by the simple unit converter to represent units. You can convert them between units. There are also versions of this for ~LinearUnit~ and ~Unitlike~.
+ - Metric :: A static utility class with instances of all of the SI named units, the 9 base dimensions, SI prefixes, some common prefixed units like the kilometre, and a few non-SI units used commonly with them.
+ - BritishImperial :: A static utility class with instances of common units in the British Imperial system (not to be confused with the US Customary system, which is also called "Imperial"; it has the same unit names but the values of a few units are different). This class and the US Customary is divided into static classes for each dimension, such as ~BritishImperial.Length~.
+ - USCustomary :: A static utility class with instances of common units in the US Customary system (not to be confused with the British Imperial system; it has the same unit names but the values of a few units are different).
+** Prefixes
+ A ~UnitPrefix~ is a simple object that can multiply a ~LinearUnit~ by a value. It can calculate a new name for the unit by combining its name and the unit's name (symbols are done similarly). It can do multiplication, division and exponentation with a number, as well as multiplication and division with another prefix; all of these work by changing the prefix's multiplier.
+** The Unit Database
+ The ~UnitDatabase~ class stores all of the unit, prefix and dimension data used by this program. It is not a representation of an actual database, just a class that stores lots of data.
+
+ Units are stored using a custom ~Map~ implementation (~PrefixedUnitMap~) which maps unit names to units. It is backed by two maps: one for units (without prefixes) and one for prefixes. It is programmed to include prefixes (so if units includes "metre" and prefixes includes "kilo", this map will include "kilometre", mapping it to a unit representing a kilometre). It is immutable, but you can modify the underlying maps, which is reflected in the ~PrefixedUnitMap~. Other than that, it is a normal map implementation.
+
+ Prefixes and dimensions are stored in normal maps.
+*** Parsing Expressions
+ Each ~UnitDatabase~ instance has four [[*ExpressionParser][ExpressionParser]] instances associated with it, for four types of expressions: unit, unit value, prefix and dimension. They are mostly similar, with operators corresponding to each operation of the corresponding class (~LinearUnit~, ~LinearUnitValue~, ~UnitPrefix~, ~ObjectProduct<BaseDimension>~). Unit and unit value expressions use linear units; nonlinear units can be used with a special syntax (like "degC(20)") and are immediately converted to a linear unit representing their base (Kelvin in this case) before operating.
+*** Parsing Files
+ There are two types of data files: unit and dimension.
+
+ Unit files contain data about units and prefixes. Each line contains the name of a unit or prefix (prefixes end in a dash, units don't) followed by an expression which defines it, separated by one or more space characters (this behaviour is defined by the static regular expression ~NAME_EXPRESSION~). Unit files are parsed line by line, each line being run through the ~addUnitOrPrefixFromLine~ method, which splits a line into name and expression, determines whether it's a unit or a prefix, and parses the expression. Because all units are defined by others, base units need to be defined with a special expression "!"; *these units should be added to the database before parsing the file*.
+
+ Dimension files are similar, only for dimensions instead of units and prefixes.
+#+LaTeX: \newpage
+* Utility Classes
+ 7Units has a few general "utility" classes. They aren't directly related to units, but are used in the units system.
+** ObjectProduct
+ An ~ObjectProduct~ represents a "product" of elements of some type. The units system uses them to represent coherent units as a product of base units, and dimensions as a product of base dimensions.
+
+ Internally, it is represented using a map mapping objects to their exponents in the product. For example, the unit "kg m^2 / s^2" (i.e. a Joule) would be represented with a map like ~[kg: 1, m: 2, s: -2]~.
+** ExpressionParser
+ The ~ExpressionParser~ class is used to parse the unit, prefix and dimension expressions that are used throughout 7Units. An expression is something like "(2 m + 30 J / N) * 8 s)". Each instance represents a type of expression, containing a way to obtain values (such as numbers or units) from the text and operations that can be done on these values (such as addition, subtraction or multiplication). Each operation also has a priority, which controls the order of operations (i.e. multiplication gets a higher priority than addition).
+
+ ~ExpressionParser~ has a parameterized type ~T~, which represents the type of the value used in the expression. The expression parser currently only supports one type of value per expression; in the expressions used by 7Units numbers are treated as a kind of unit or prefix. Operators are represented by internal types; the system distinguishes between unary operators (those that take a single value, like negation) and binary operators (those that take 2 values, like +, -, * or /).
+
+ Expressions are parsed in 2 steps:
+ 1. Convert the expression to [[https://en.wikipedia.org/wiki/Reverse_Polish_notation][Reverse Polish Notation]], where operators come *after* the values they operate on, and brackets and the order of operations are not necessary. For example, "2 + 5" becomes "~2 5 +~", "(1 + 2) * 3" becomes "~1 2 + 3 *~" and the example expression earlier becomes "~2 m * 30 J * N / + 8 s * *~". This makes it simple to evaluate - early calculators used RPN for a good reason!
+ 2. Evaluate the RPN expression. This can be done simply with a for loop and a stack. For each token in the expression, the progam does the following:
+ - if it is a number or unit, add it to the stack.
+ - if it is a unary operator, take one value from the stack, apply the operator to it, and put the result into the stack.
+ - if it is a binary operator, take two values from the stack, apply the operator to them, and put the result into the stack.
+ After evaluating the last token, there should be one value left in the stack - the answer. If there isn't, the original expression was malformed.
+** Math Classes
+ There are two simple math classes in 7Units:
+ - ~UncertainDouble~ :: Like a ~double~, but with an uncertainty (e.g. \(2.0 \pm 0.4\)). The operations are like those of the regular Double, only they also calculate the uncertainty of the final value. They also have "exact" versions to help interoperation between ~double~ and ~UncertainDouble~. It is used by the converter's Scientific Precision setting.
+ - ~DecimalComparison~ :: A static utility class that contains a few alternate equals() methods for ~double~ and ~UncertainDouble~. These methods allow a slight (configurable) difference between values to still be considered equal, to fight roundoff error.
+** Collection Classes
+ The ~ConditionalExistenceCollections~ class contains wrapper implementations of ~Collection~, ~Iterator~, ~Map~ and ~Set~. These implementations ignore elements that do not pass a certain condition - if an element fails the condition, ~contains~ will return false, the iterator will skip past it, it won't be counted in ~size~, etc. even if it exists in the original collection. Effectively, any element of the original collection that fails the test does not exist.
diff --git a/docs/design.pdf b/docs/design.pdf
new file mode 100644
index 0000000..fd1f2f1
--- /dev/null
+++ b/docs/design.pdf
Binary files differ
diff --git a/docs/design.tex b/docs/design.tex
new file mode 100644
index 0000000..178a1c8
--- /dev/null
+++ b/docs/design.tex
@@ -0,0 +1,135 @@
+% Created 2021-08-26 Thu 11:25
+% Intended LaTeX compiler: pdflatex
+\documentclass[11pt]{article}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{graphicx}
+\usepackage{grffile}
+\usepackage{longtable}
+\usepackage{wrapfig}
+\usepackage{rotating}
+\usepackage[normalem]{ulem}
+\usepackage{amsmath}
+\usepackage{textcomp}
+\usepackage{amssymb}
+\usepackage{capt-of}
+\usepackage{hyperref}
+\usepackage[a4paper, lmargin=25mm, rmargin=25mm, tmargin=25mm, bmargin=25mm]{geometry}
+\usepackage{xurl}
+\date{2021 August 26}
+\title{7Units Design Document\\\medskip
+\large For version 0.3.1}
+\hypersetup{
+ pdfauthor={},
+ pdftitle={7Units Design Document},
+ pdfkeywords={},
+ pdfsubject={},
+ pdfcreator={Emacs 27.1 (Org mode 9.4.6)},
+ pdflang={English}}
+\begin{document}
+
+\maketitle
+\tableofcontents
+
+\newpage
+
+\section{Introduction}
+\label{sec:orgc81fddd}
+7Units is a program that can convert between units. This document details the internal design of 7Units, intended to be used by current and future developers.
+
+The frontend code is currently subject to change, so it is not included in the current version of this document.
+\section{Unit System Design}
+\label{sec:org9d0655d}
+Any code related to the backend unit system is stored in the \texttt{sevenUnits.unit} package.
+
+Here is a class diagram of the system. Unimportant methods, methods inherited from Object, getters and setters have been omitted.
+\begin{center}
+\includegraphics[width=.9\linewidth]{./diagrams/units-class-diagram.plantuml.png}
+\end{center}
+\newpage
+\subsection{Dimensions}
+\label{sec:org1e98dda}
+Dimensions represent what a unit is measuring, such as length, time, or energy. Dimensions are represented as an \hyperref[sec:orgc7c5740]{ObjectProduct}<BaseDimension>, where \texttt{BaseDimension} is a very simple class (its only properties are a name and a symbol) which represents the dimension of a base unit; these base dimensions can be multiplied to create all other Dimensions.
+\subsection{Unit Classes}
+\label{sec:orgd5ff0fb}
+Units are internally represented by the abstract class \texttt{Unit}. All units have an \hyperref[sec:orgc7c5740]{ObjectProduct}<BaseUnit> (referred to as the base) that they are based on, a dimension (ObjectProduct<BaseDimension>), one or more names and a symbol (these last two bits of data are contained in the \texttt{NameSymbol} class). The dimension is calculated from the base unit when needed; the variable is just a cache. It has two constructors: a package-private one used to make \texttt{BaseUnit} instances, and a protected one used to make general units (for other subclasses of \texttt{Unit}). All unit classes are immutable.
+
+Units also have two conversion functions - one which converts from a value expressed in this unit to its base unit, and another which converts from a value expressed in the base unit to this unit. In \texttt{Unit}, they are defined as two abstract methods. This allows you to convert from any unit to any other (as long as they have the same base, i.e. you aren't converting metres to pounds). To convert from A to B, first convert from A to its base, then convert from the base to B.
+
+\texttt{BaseUnit} represents a unit that all other units are defined by. All of the units used by this system are defined by seven SI \texttt{BaseUnit} instances (metre, second, kilogram, ampere, kelvin, mole, candela; this is what 7Units is named after) and two non-SI \texttt{BaseUnit} instances (US dollar and bit). Because base units are themselves units (and should be able to be used as units), \texttt{BaseUnit} is a subclass of \texttt{Unit}, using its own package-private constructor.
+
+However, most units are instances of \texttt{LinearUnit}, another subclass of \texttt{Unit}. \texttt{LinearUnit} represents a unit that is \emph{a product of a base unit and a constant called the \textbf{conversion factor}}. Most units you've ever used fall under this definition, the only common exceptions are degrees Celsius and Fahrenheit. This simplicity allows the \texttt{LinearUnit} to do many things:
+\begin{itemize}
+\item It can implement conversion to and from the base as multiplying and dividing by the conversion factor respectively
+\item You can easily create new units by multiplying or dividing a \texttt{LinearUnit} by a number (for example, kilometre = metre * 1000). This can be easily implemented as multiplying this unit's conversion factor by the multiplier and returning a new \texttt{LinearUnit} with that conversion factor factor.
+\item You can add or subtract two \texttt{LinearUnit} instances to create a third (as long as they have the same base) by adding or subtracting the conversion factor.
+\item You can multiply or divide any two \texttt{LinearUnit} instances to create a third by multiplying or dividing the bases and conversion factors.
+\item Note that any operations will return a unit without name(s) or a symbol. All unit classes have a \texttt{withName} method that returns a copy of them with different names and/or a different symbol (all of this info is contained in the \texttt{NameSymbol} class)
+\end{itemize}
+
+There are a few more classes which play small roles in the unit system:
+\begin{description}
+\item[{Unitlike}] A class that is like a unit, but its "value" can be any class. The only use of this class right now is to implement \texttt{MultiUnit}, a combination of units (like "foot + inch", commonly used in North America for measuring height); its "value" is a list of numbers.
+\item[{FunctionalUnit}] A convenience class that implements the two conversion functions of \texttt{Unit} using \texttt{DoubleUnaryOperator} instances. This is used internally to implement degrees Celsius and Fahrenheit. There is also a version of this for \texttt{Unitlike}, \texttt{FunctionalUnitlike}.
+\item[{UnitValue}] A value expressed as a certain unit (such as "7 inches"). This class is used by the simple unit converter to represent units. You can convert them between units. There are also versions of this for \texttt{LinearUnit} and \texttt{Unitlike}.
+\item[{Metric}] A static utility class with instances of all of the SI named units, the 9 base dimensions, SI prefixes, some common prefixed units like the kilometre, and a few non-SI units used commonly with them.
+\item[{BritishImperial}] A static utility class with instances of common units in the British Imperial system (not to be confused with the US Customary system, which is also called "Imperial"; it has the same unit names but the values of a few units are different). This class and the US Customary is divided into static classes for each dimension, such as \texttt{BritishImperial.Length}.
+\item[{USCustomary}] A static utility class with instances of common units in the US Customary system (not to be confused with the British Imperial system; it has the same unit names but the values of a few units are different).
+\end{description}
+\subsection{Prefixes}
+\label{sec:org1aaa92c}
+A \texttt{UnitPrefix} is a simple object that can multiply a \texttt{LinearUnit} by a value. It can calculate a new name for the unit by combining its name and the unit's name (symbols are done similarly). It can do multiplication, division and exponentation with a number, as well as multiplication and division with another prefix; all of these work by changing the prefix's multiplier.
+\subsection{The Unit Database}
+\label{sec:org7c6cf6d}
+The \texttt{UnitDatabase} class stores all of the unit, prefix and dimension data used by this program. It is not a representation of an actual database, just a class that stores lots of data.
+
+Units are stored using a custom \texttt{Map} implementation (\texttt{PrefixedUnitMap}) which maps unit names to units. It is backed by two maps: one for units (without prefixes) and one for prefixes. It is programmed to include prefixes (so if units includes "metre" and prefixes includes "kilo", this map will include "kilometre", mapping it to a unit representing a kilometre). It is immutable, but you can modify the underlying maps, which is reflected in the \texttt{PrefixedUnitMap}. Other than that, it is a normal map implementation.
+
+Prefixes and dimensions are stored in normal maps.
+\subsubsection{Parsing Expressions}
+\label{sec:org8392990}
+Each \texttt{UnitDatabase} instance has four \hyperref[sec:orgb091347]{ExpressionParser} instances associated with it, for four types of expressions: unit, unit value, prefix and dimension. They are mostly similar, with operators corresponding to each operation of the corresponding class (\texttt{LinearUnit}, \texttt{LinearUnitValue}, \texttt{UnitPrefix}, \texttt{ObjectProduct<BaseDimension>}). Unit and unit value expressions use linear units; nonlinear units can be used with a special syntax (like "degC(20)") and are immediately converted to a linear unit representing their base (Kelvin in this case) before operating.
+\subsubsection{Parsing Files}
+\label{sec:orgd4ad341}
+There are two types of data files: unit and dimension.
+
+Unit files contain data about units and prefixes. Each line contains the name of a unit or prefix (prefixes end in a dash, units don't) followed by an expression which defines it, separated by one or more space characters (this behaviour is defined by the static regular expression \texttt{NAME\_EXPRESSION}). Unit files are parsed line by line, each line being run through the \texttt{addUnitOrPrefixFromLine} method, which splits a line into name and expression, determines whether it's a unit or a prefix, and parses the expression. Because all units are defined by others, base units need to be defined with a special expression "!"; \textbf{these units should be added to the database before parsing the file}.
+
+Dimension files are similar, only for dimensions instead of units and prefixes.
+\newpage
+\section{Utility Classes}
+\label{sec:org251cb6a}
+7Units has a few general "utility" classes. They aren't directly related to units, but are used in the units system.
+\subsection{ObjectProduct}
+\label{sec:orgc7c5740}
+An \texttt{ObjectProduct} represents a "product" of elements of some type. The units system uses them to represent coherent units as a product of base units, and dimensions as a product of base dimensions.
+
+Internally, it is represented using a map mapping objects to their exponents in the product. For example, the unit "kg m\textsuperscript{2} / s\textsuperscript{2}" (i.e. a Joule) would be represented with a map like \texttt{[kg: 1, m: 2, s: -2]}.
+\subsection{ExpressionParser}
+\label{sec:orgb091347}
+The \texttt{ExpressionParser} class is used to parse the unit, prefix and dimension expressions that are used throughout 7Units. An expression is something like "(2 m + 30 J / N) * 8 s)". Each instance represents a type of expression, containing a way to obtain values (such as numbers or units) from the text and operations that can be done on these values (such as addition, subtraction or multiplication). Each operation also has a priority, which controls the order of operations (i.e. multiplication gets a higher priority than addition).
+
+\texttt{ExpressionParser} has a parameterized type \texttt{T}, which represents the type of the value used in the expression. The expression parser currently only supports one type of value per expression; in the expressions used by 7Units numbers are treated as a kind of unit or prefix. Operators are represented by internal types; the system distinguishes between unary operators (those that take a single value, like negation) and binary operators (those that take 2 values, like +, -, * or /).
+
+Expressions are parsed in 2 steps:
+\begin{enumerate}
+\item Convert the expression to \href{https://en.wikipedia.org/wiki/Reverse\_Polish\_notation}{Reverse Polish Notation}, where operators come \textbf{after} the values they operate on, and brackets and the order of operations are not necessary. For example, "2 + 5" becomes "\texttt{2 5 +}", "(1 + 2) * 3" becomes "\texttt{1 2 + 3 *}" and the example expression earlier becomes "\texttt{2 m * 30 J * N / + 8 s * *}". This makes it simple to evaluate - early calculators used RPN for a good reason!
+\item Evaluate the RPN expression. This can be done simply with a for loop and a stack. For each token in the expression, the progam does the following:
+\begin{itemize}
+\item if it is a number or unit, add it to the stack.
+\item if it is a unary operator, take one value from the stack, apply the operator to it, and put the result into the stack.
+\item if it is a binary operator, take two values from the stack, apply the operator to them, and put the result into the stack.
+\end{itemize}
+After evaluating the last token, there should be one value left in the stack - the answer. If there isn't, the original expression was malformed.
+\end{enumerate}
+\subsection{Math Classes}
+\label{sec:orgb4a476a}
+There are two simple math classes in 7Units:
+\begin{description}
+\item[{\texttt{UncertainDouble}}] Like a \texttt{double}, but with an uncertainty (e.g. \(2.0 \pm 0.4\)). The operations are like those of the regular Double, only they also calculate the uncertainty of the final value. They also have "exact" versions to help interoperation between \texttt{double} and \texttt{UncertainDouble}. It is used by the converter's Scientific Precision setting.
+\item[{\texttt{DecimalComparison}}] A static utility class that contains a few alternate equals() methods for \texttt{double} and \texttt{UncertainDouble}. These methods allow a slight (configurable) difference between values to still be considered equal, to fight roundoff error.
+\end{description}
+\subsection{Collection Classes}
+\label{sec:org4a3e6a1}
+The \texttt{ConditionalExistenceCollections} class contains wrapper implementations of \texttt{Collection}, \texttt{Iterator}, \texttt{Map} and \texttt{Set}. These implementations ignore elements that do not pass a certain condition - if an element fails the condition, \texttt{contains} will return false, the iterator will skip past it, it won't be counted in \texttt{size}, etc. even if it exists in the original collection. Effectively, any element of the original collection that fails the test does not exist.
+\end{document}
diff --git a/docs/diagrams/units-class-diagram.plantuml.png b/docs/diagrams/units-class-diagram.plantuml.png
new file mode 100644
index 0000000..7c68ab5
--- /dev/null
+++ b/docs/diagrams/units-class-diagram.plantuml.png
Binary files differ
diff --git a/docs/diagrams/units-class-diagram.plantuml.txt b/docs/diagrams/units-class-diagram.plantuml.txt
new file mode 100644
index 0000000..7baf168
--- /dev/null
+++ b/docs/diagrams/units-class-diagram.plantuml.txt
@@ -0,0 +1,72 @@
+@startuml
+abstract class Unit {
+ -unitBase : ObjectProduct<BaseUnit>
+ -nameSymbol : NameSymbol
+ -dimension : ObjectProduct<BaseDimension>
+ +{static} fromConversionFunctions(ObjectProduct<BaseUnit>, DoubleUnaryOperator, DoubleUnaryOperator) : Unit
+ #Unit(ObjectProduct<BaseUnit>, NameSymbol) : Unit
+ ~Unit(NameSymbol) : Unit
+ +canConvertTo(Unit) : boolean
+ +convertTo(Unit, double) : double
+ #convertFromBase(double) : double
+ #convertToBase(double) : double
+ +isMetric() : boolean
+ +withName(NameSymbol) : Unit
+}
+class BaseUnit {
+ -dimension : BaseDimension
+ -BaseUnit(BaseDimension, String, String, Set<String) : BaseUnit
+ +asLinearUnit() : LinearUnit
+}
+class LinearUnit {
+ -conversionFactor : double
+ +{static} valueOf(ObjectProduct<BaseUnit>, double) : LinearUnit
+ -LinearUnit(ObjectProduct<BaseUnit>, double, NameSymbol) : LinearUnit
+ +convertTo(LinearUnit, UncertainDouble) : UncertainDouble
+ +plus(LinearUnit) : LinearUnit
+ +minus(LinearUnit) : LinearUnit
+ +times(LinearUnit) : LinearUnit
+ +dividedBy(LinearUnit) : LinearUnit
+ +times(double) : LinearUnit
+ +dividedBy(double) : LinearUnit
+ +toExponent(int) : LinearUnit
+ +withPrefix(UnitPrefix) : LinearUnit
+ +withName(NameSymbol) : LinearUnit
+}
+class UnitPrefix {
+ -multiplier : double
+ +times(double) : UnitPrefix
+ +dividedBy(double) : UnitPrefix
+}
+class UnitDatabase {
+ -prefixlessUnits : Map<String, Unit>
+ -units : Map<String, Unit>
+ -prefixes : Map<String, UnitPrefix>
+ -dimensions : Map<String, ObjectProduct<BaseDimension>>
+ -unitExpressionParser : ExpressionParser<LinearUnit>
+ +loadUnitsFile(Path)
+ -addUnitOrPrefixFromLine(String, long)
+ +addUnit(String, Unit)
+ +containsUnitName(String) : boolean
+ +evaluateUnitExpression(String) : LinearUnitValue
+ +getUnit(String) : Unit
+}
+class UnitValue {
+ -unit : Unit
+ -value : double
+ +canConvertTo(Unit) : boolean
+ +convertTo(Unit) : UnitValue
+ +convertToLinear(LinearUnit) : LinearUnitValue
+}
+
+Unit <|-- BaseUnit
+Unit --* BaseUnit
+BaseDimension -o BaseUnit
+Unit <|-- LinearUnit
+Unit *- SI
+UnitValue --o Unit
+UnitDatabase --* Unit
+UnitDatabase --* UnitPrefix
+UnitDatabase --* BaseDimension
+UnitDatabase -* "4" ExpressionParser
+@enduml
diff --git a/docs/manual.org b/docs/manual.org
new file mode 100644
index 0000000..086ae5d
--- /dev/null
+++ b/docs/manual.org
@@ -0,0 +1,83 @@
+#+TITLE: 7Units User Manual
+#+SUBTITLE: For Version 0.3.1
+#+DATE: 2021 July 6
+#+LaTeX_HEADER: \usepackage[a4paper, lmargin=25mm, rmargin=25mm, tmargin=25mm, bmargin=25mm]{geometry}
+
+#+LaTeX: \newpage
+* Introduction and Purpose
+ 7Units is a program that can be used to convert units. This document outlines how to use the program.
+* System Requirements
+ - Works on all major operating systems \\
+ *NOTE:* All screenshots in this document were taken on Windows 10. If you use a different operating system, the program will probably look different than what is shown.
+ - Java version 11-15 required
+# installation instructions go here - wait until git repository is fixed/set up
+#+LaTeX: \newpage
+* How to Use 7Units
+** Simple Unit Conversion
+ 1. Select the "Convert Units" tab if it is not already selected. You should see a screen like in figure [[main-interface-dimension]]:
+ #+CAPTION: Taken in version 0.3.0
+ #+ATTR_LaTeX: :height 250px
+ #+name: main-interface-dimension
+ [[../screenshots/main-interface-dimension-converter.png]]
+ 2. Use the dropdown box at the top to select what kind of unit to convert (length, mass, speed, etc.)
+ 3. Select the unit to convert /from/ on the left.
+ 4. Select the unit to convert /to/ on the right.
+ 5. Enter the value to convert in the box above the convert button. The program should look something like in figure [[sample-conversion-dimension]]:
+ #+CAPTION: This image, taken in version 0.3.0, shows the user about to convert 35 miles to kilometres.
+ #+attr_latex: :height 250px
+ #+name: sample-conversion-dimension
+ [[../screenshots/sample-conversion-dimension-converter.png]]
+ 6. Press the "Convert" button. The result will be shown below the "Convert" button. This is shown in figure [[sample-results-dimension]]
+ #+CAPTION: The result of the above conversion
+ #+attr_latex: :height 250px
+ #+name: sample-results-dimension
+ [[../screenshots/sample-conversion-results-dimension-converter.png]]
+** Complex Unit Conversion
+ 1. Select the "Convert Unit Expressions" if it is not already selected. You should see a screen like in figure [[main-interface-expression]]:
+ #+CAPTION: Taken in version 0.3.0
+ #+attr_latex: :height 250px
+ #+name: main-interface-expression
+ [[../screenshots/main-interface-expression-converter.png]]
+ 2. Enter a [[*Unit Expressions][unit expression]] in the From box. This can be something like "~7 km~" or "~6 ft - 2 in~" or "~3 kg m + 9 lb ft + (35 mm)^2 * (85 oz) / (20 in)~".
+ 3. Enter a unit name (or another unit expression) in the To box.
+ 4. Press the Convert button. This will calculate the value of the first expression, and convert it to a multiple of the second unit (or expression).
+ #+CAPTION: A sample calculation. Divides ~100 km~ by ~35 km/h~ and converts the result to minutes. This could be used to calculate how long (in minutes) it takes to go 100 kilometres at a speed of 35 km/h.
+ #+attr_latex: :height 250px
+ #+name: sample-results-expression
+ [[../screenshots/sample-conversion-results-expression-converter.png]]
+* 7Units Settings
+ All settings can be accessed in the tab with the gear icon.
+ #+CAPTION: The settings menu, as of version 0.3.0
+ #+ATTR_LaTeX: :height 250px
+ [[../screenshots/main-interface-settings.png]]
+** Rounding Settings
+ These settings control how the output of a unit conversion is rounded.
+ - Fixed Precision :: Round to a fixed number of [[https://en.wikipedia.org/wiki/Significant_figures][significant digits]]. The number of significant digits is controlled by the precision slider below.
+ - Fixed Decimal Places :: Round to a fixed number of digits after the decimal point. The number of decimal places is also controlled by the precision slider below.
+ - Scientific Precision :: Intelligent rounding which uses the precision of the input value(s) to determine the output precision. Not affected by the precision slider.
+** Prefix Repetition Settings
+ These settings control when you are allowed to repeat unit prefixes (e.g. kilokilometre)
+ - No Repetition :: Units may only have one prefix.
+ - No Restriction :: Units may have any number of prefixes.
+ - Complex Repetition :: A complex rule which makes it so that each power of 10 has one and only one prefix combination. Units may have the following prefixes:
+ - one of: centi, deci, deca, hecto
+ - one of: zepto, atto, femto, pico, nano, micro, milli, kilo, mega, giga, tera, peta, exa, zetta
+ - any number of yocto or yotta
+ - they must be in this order
+ - all prefixes must be of the same sign (either all magnifying or all reducing)
+** Miscellaneous Settings
+ - Convert One Way Only :: In the simple conversion tab, only imperial/customary units will be shown on the left, and only metric units[fn:1] will be shown on the right. Units listed in the exceptions file (~src/main/resources/metric_exceptions.txt~) will be shown on both sides. This is a way to reduce the number of options you must search through if you only convert one way. The expressions tab is unaffected.
+ - Show Duplicates in "Convert Units" :: If unchecked, any unit that has multiple names will only have one included in the Convert Units lists. The selected name will be the longest; if there are multiple longest names one is selected arbitrarily. You will still be able to use these alternate names in the expressions tab.
+* Appendices
+** Unit Expressions
+ A unit expression is simply a math expression where the values being operated on are units or numbers. The operations that can be used are (in order of precedence):
+ - Exponentiation (^); the exponent must be an integer. Both units and numbers can be raised to an exponent
+ - Multiplication (*) and division (/). Multiplication can also be done with a space (so "15 meter" is the same thing as "15 * meter").
+ - Addition (+) and subtraction (-). They can only be done between units of the same dimension (measuring the same thing). So you can add metres, inches and feet together, and you can add joules and calories together, but you can't add metres to seconds, or feet to calories, or watts to pounds.
+
+ Brackets can be used to manipulate the order of operations, and nonlinear units like Celsius and Fahrenheit cannot be used in expressions. You can use a value in a nonlinear unit by putting brackets after it - for example, degC(12) represents the value 12 \deg C
+** Other Expressions
+ There are also a simplified version of expressions for prefixes and dimensions. Only multiplication, division and exponentation are supported. Currently, exponentation is not supported for dimensions, but that may be fixed in the future.
+* Footnotes
+
+[fn:1] 7Units's definition of "metric" is stricter than the SI, but all of the common units that are commonly considered metric but not included in 7Units's definition are included in the exceptions file.
diff --git a/docs/manual.pdf b/docs/manual.pdf
new file mode 100644
index 0000000..e6cbb5d
--- /dev/null
+++ b/docs/manual.pdf
Binary files differ
diff --git a/docs/manual.tex b/docs/manual.tex
new file mode 100644
index 0000000..25a5cf7
--- /dev/null
+++ b/docs/manual.tex
@@ -0,0 +1,143 @@
+% Created 2021-07-06 Tue 15:22
+% Intended LaTeX compiler: pdflatex
+\documentclass[11pt]{article}
+\usepackage[utf8]{inputenc}
+\usepackage[T1]{fontenc}
+\usepackage{graphicx}
+\usepackage{grffile}
+\usepackage{longtable}
+\usepackage{wrapfig}
+\usepackage{rotating}
+\usepackage[normalem]{ulem}
+\usepackage{amsmath}
+\usepackage{textcomp}
+\usepackage{amssymb}
+\usepackage{capt-of}
+\usepackage{hyperref}
+\usepackage[a4paper, lmargin=25mm, rmargin=25mm, tmargin=25mm, bmargin=25mm]{geometry}
+\date{2021 July 6}
+\title{7Units User Manual\\\medskip
+\large For Version 0.3.1}
+\hypersetup{
+ pdfauthor={},
+ pdftitle={7Units User Manual},
+ pdfkeywords={},
+ pdfsubject={},
+ pdfcreator={Emacs 27.1 (Org mode 9.4.6)},
+ pdflang={English}}
+\begin{document}
+
+\maketitle
+\tableofcontents
+
+\newpage
+\section{Introduction and Purpose}
+\label{sec:org9bdf09d}
+7Units is a program that can be used to convert units. This document outlines how to use the program.
+\section{System Requirements}
+\label{sec:org6fc29c1}
+\begin{itemize}
+\item Works on all major operating systems \\
+\textbf{NOTE:} All screenshots in this document were taken on Windows 10. If you use a different operating system, the program will probably look different than what is shown.
+\item Java version 11-15 required
+\end{itemize}
+
+\newpage
+\section{How to Use 7Units}
+\label{sec:org12dfe6f}
+\subsection{Simple Unit Conversion}
+\label{sec:org49a020a}
+\begin{enumerate}
+\item Select the "Convert Units" tab if it is not already selected. You should see a screen like in figure \ref{main-interface-dimension}:
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=250px]{../screenshots/main-interface-dimension-converter.png}
+\caption{\label{main-interface-dimension}Taken in version 0.3.0}
+\end{figure}
+\item Use the dropdown box at the top to select what kind of unit to convert (length, mass, speed, etc.)
+\item Select the unit to convert \emph{from} on the left.
+\item Select the unit to convert \emph{to} on the right.
+\item Enter the value to convert in the box above the convert button. The program should look something like in figure \ref{sample-conversion-dimension}:
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=250px]{../screenshots/sample-conversion-dimension-converter.png}
+\caption{\label{sample-conversion-dimension}This image, taken in version 0.3.0, shows the user about to convert 35 miles to kilometres.}
+\end{figure}
+\item Press the "Convert" button. The result will be shown below the "Convert" button. This is shown in figure \ref{sample-results-dimension}
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=250px]{../screenshots/sample-conversion-results-dimension-converter.png}
+\caption{\label{sample-results-dimension}The result of the above conversion}
+\end{figure}
+\end{enumerate}
+\subsection{Complex Unit Conversion}
+\label{sec:org5433cd5}
+\begin{enumerate}
+\item Select the "Convert Unit Expressions" if it is not already selected. You should see a screen like in figure \ref{main-interface-expression}:
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=250px]{../screenshots/main-interface-expression-converter.png}
+\caption{\label{main-interface-expression}Taken in version 0.3.0}
+\end{figure}
+\item Enter a \hyperref[sec:org05dd82b]{unit expression} in the From box. This can be something like "\texttt{7 km}" or "\texttt{6 ft - 2 in}" or "\texttt{3 kg m + 9 lb ft + (35 mm)\textasciicircum{}2 * (85 oz) / (20 in)}".
+\item Enter a unit name (or another unit expression) in the To box.
+\item Press the Convert button. This will calculate the value of the first expression, and convert it to a multiple of the second unit (or expression).
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=250px]{../screenshots/sample-conversion-results-expression-converter.png}
+\caption{\label{sample-results-expression}A sample calculation. Divides \texttt{100 km} by \texttt{35 km/h} and converts the result to minutes. This could be used to calculate how long (in minutes) it takes to go 100 kilometres at a speed of 35 km/h.}
+\end{figure}
+\end{enumerate}
+\section{7Units Settings}
+\label{sec:org59fb50d}
+All settings can be accessed in the tab with the gear icon.
+\begin{figure}[htbp]
+\centering
+\includegraphics[height=250px]{../screenshots/main-interface-settings.png}
+\caption{The settings menu, as of version 0.3.0}
+\end{figure}
+\subsection{Rounding Settings}
+\label{sec:org328f0e1}
+These settings control how the output of a unit conversion is rounded.
+\begin{description}
+\item[{Fixed Precision}] Round to a fixed number of \href{https://en.wikipedia.org/wiki/Significant\_figures}{significant digits}. The number of significant digits is controlled by the precision slider below.
+\item[{Fixed Decimal Places}] Round to a fixed number of digits after the decimal point. The number of decimal places is also controlled by the precision slider below.
+\item[{Scientific Precision}] Intelligent rounding which uses the precision of the input value(s) to determine the output precision. Not affected by the precision slider.
+\end{description}
+\subsection{Prefix Repetition Settings}
+\label{sec:org859bd80}
+These settings control when you are allowed to repeat unit prefixes (e.g. kilokilometre)
+\begin{description}
+\item[{No Repetition}] Units may only have one prefix.
+\item[{No Restriction}] Units may have any number of prefixes.
+\item[{Complex Repetition}] A complex rule which makes it so that each power of 10 has one and only one prefix combination. Units may have the following prefixes:
+\begin{itemize}
+\item one of: centi, deci, deca, hecto
+\item one of: zepto, atto, femto, pico, nano, micro, milli, kilo, mega, giga, tera, peta, exa, zetta
+\item any number of yocto or yotta
+\item they must be in this order
+\item all prefixes must be of the same sign (either all magnifying or all reducing)
+\end{itemize}
+\end{description}
+\subsection{Miscellaneous Settings}
+\label{sec:org7345e44}
+\begin{description}
+\item[{Convert One Way Only}] In the simple conversion tab, only imperial/customary units will be shown on the left, and only metric units\footnote{7Units's definition of "metric" is stricter than the SI, but all of the common units that are commonly considered metric but not included in 7Units's definition are included in the exceptions file.} will be shown on the right. Units listed in the exceptions file (\texttt{src/main/resources/metric\_exceptions.txt}) will be shown on both sides. This is a way to reduce the number of options you must search through if you only convert one way. The expressions tab is unaffected.
+\item[{Show Duplicates in "Convert Units"}] If unchecked, any unit that has multiple names will only have one included in the Convert Units lists. The selected name will be the longest; if there are multiple longest names one is selected arbitrarily. You will still be able to use these alternate names in the expressions tab.
+\end{description}
+\section{Appendices}
+\label{sec:orgee83bb3}
+\subsection{Unit Expressions}
+\label{sec:org05dd82b}
+A unit expression is simply a math expression where the values being operated on are units or numbers. The operations that can be used are (in order of precedence):
+\begin{itemize}
+\item Exponentiation (\^{}); the exponent must be an integer. Both units and numbers can be raised to an exponent
+\item Multiplication (*) and division (/). Multiplication can also be done with a space (so "15 meter" is the same thing as "15 * meter").
+\item Addition (+) and subtraction (-). They can only be done between units of the same dimension (measuring the same thing). So you can add metres, inches and feet together, and you can add joules and calories together, but you can't add metres to seconds, or feet to calories, or watts to pounds.
+\end{itemize}
+
+Brackets can be used to manipulate the order of operations, and nonlinear units like Celsius and Fahrenheit cannot be used in expressions. You can use a value in a nonlinear unit by putting brackets after it - for example, degC(12) represents the value 12 \textdegree{} C
+\subsection{Other Expressions}
+\label{sec:org8014464}
+There are also a simplified version of expressions for prefixes and dimensions. Only multiplication, division and exponentation are supported. Currently, exponentation is not supported for dimensions, but that may be fixed in the future.
+\end{document}
diff --git a/screenshots/main-interface-dimension-converter.png b/screenshots/main-interface-dimension-converter.png
new file mode 100644
index 0000000..7d8bd4d
--- /dev/null
+++ b/screenshots/main-interface-dimension-converter.png
Binary files differ
diff --git a/screenshots/main-interface-expression-converter.png b/screenshots/main-interface-expression-converter.png
new file mode 100644
index 0000000..e5e0b2e
--- /dev/null
+++ b/screenshots/main-interface-expression-converter.png
Binary files differ
diff --git a/screenshots/main-interface-settings.png b/screenshots/main-interface-settings.png
new file mode 100644
index 0000000..97b711c
--- /dev/null
+++ b/screenshots/main-interface-settings.png
Binary files differ
diff --git a/screenshots/sample-conversion-dimension-converter.png b/screenshots/sample-conversion-dimension-converter.png
new file mode 100644
index 0000000..4246266
--- /dev/null
+++ b/screenshots/sample-conversion-dimension-converter.png
Binary files differ
diff --git a/screenshots/sample-conversion-results-dimension-converter.png b/screenshots/sample-conversion-results-dimension-converter.png
new file mode 100644
index 0000000..2336070
--- /dev/null
+++ b/screenshots/sample-conversion-results-dimension-converter.png
Binary files differ
diff --git a/screenshots/sample-conversion-results-expression-converter.png b/screenshots/sample-conversion-results-expression-converter.png
new file mode 100644
index 0000000..1f44547
--- /dev/null
+++ b/screenshots/sample-conversion-results-expression-converter.png
Binary files differ
diff --git a/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java b/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
index 835651e..6b6abf0 100644
--- a/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
+++ b/src/main/java/sevenUnits/converterGUI/DefaultPrefixRepetitionRule.java
@@ -6,7 +6,7 @@ package sevenUnits.converterGUI;
import java.util.List;
import java.util.function.Predicate;
-import sevenUnits.unit.SI;
+import sevenUnits.unit.Metric;
import sevenUnits.unit.UnitPrefix;
/**
@@ -49,7 +49,7 @@ enum DefaultPrefixRepetitionRule implements Predicate<List<UnitPrefix>> {
// if the first prefix is non-metric (including binary prefixes),
// assume we are using non-metric prefixes
// non-metric prefixes are allowed, but can't be repeated.
- if (!SI.DECIMAL_PREFIXES.contains(prefixes.get(0)))
+ if (!Metric.DECIMAL_PREFIXES.contains(prefixes.get(0)))
return NO_REPETITION.test(prefixes);
int part = 0; // 0=yotta/yoctos, 1=kilo-zetta/milli-zepto,
@@ -58,7 +58,7 @@ enum DefaultPrefixRepetitionRule implements Predicate<List<UnitPrefix>> {
for (final UnitPrefix prefix : prefixes) {
// check that the current prefix is metric and appropriately
// magnifying/reducing
- if (!SI.DECIMAL_PREFIXES.contains(prefix))
+ if (!Metric.DECIMAL_PREFIXES.contains(prefix))
return false;
if (magnifying != prefix.getMultiplier() > 1)
return false;
@@ -72,7 +72,7 @@ enum DefaultPrefixRepetitionRule implements Predicate<List<UnitPrefix>> {
break;
case 1:
// after a kilo-zetta, only deka/hecto are valid
- if (SI.THOUSAND_PREFIXES.contains(prefix))
+ if (Metric.THOUSAND_PREFIXES.contains(prefix))
return false;
break;
case 2:
@@ -81,9 +81,9 @@ enum DefaultPrefixRepetitionRule implements Predicate<List<UnitPrefix>> {
}
// set part
- if (SI.YOTTA.equals(prefix) || SI.YOCTO.equals(prefix)) {
+ if (Metric.YOTTA.equals(prefix) || Metric.YOCTO.equals(prefix)) {
part = 0;
- } else if (SI.THOUSAND_PREFIXES.contains(prefix)) {
+ } else if (Metric.THOUSAND_PREFIXES.contains(prefix)) {
part = 1;
} else {
part = 2;
diff --git a/src/main/java/sevenUnits/converterGUI/SevenUnitsGUI.java b/src/main/java/sevenUnits/converterGUI/SevenUnitsGUI.java
index fb498da..bfd5974 100644
--- a/src/main/java/sevenUnits/converterGUI/SevenUnitsGUI.java
+++ b/src/main/java/sevenUnits/converterGUI/SevenUnitsGUI.java
@@ -65,18 +65,18 @@ import javax.swing.WindowConstants;
import javax.swing.border.TitledBorder;
import sevenUnits.ProgramInfo;
-import sevenUnits.math.ConditionalExistenceCollections;
-import sevenUnits.math.ObjectProduct;
import sevenUnits.unit.BaseDimension;
import sevenUnits.unit.BritishImperial;
import sevenUnits.unit.LinearUnit;
import sevenUnits.unit.LinearUnitValue;
import sevenUnits.unit.NameSymbol;
-import sevenUnits.unit.SI;
+import sevenUnits.unit.Metric;
import sevenUnits.unit.Unit;
import sevenUnits.unit.UnitDatabase;
import sevenUnits.unit.UnitPrefix;
import sevenUnits.unit.UnitValue;
+import sevenUnits.utils.ConditionalExistenceCollections;
+import sevenUnits.utils.ObjectProduct;
/**
* @author Adrien Hopkins
@@ -110,25 +110,25 @@ final class SevenUnitsGUI {
* @since v0.2.0
*/
private static void addDefaults(final UnitDatabase database) {
- database.addUnit("metre", SI.METRE);
- database.addUnit("kilogram", SI.KILOGRAM);
- database.addUnit("gram", SI.KILOGRAM.dividedBy(1000));
- database.addUnit("second", SI.SECOND);
- database.addUnit("ampere", SI.AMPERE);
- database.addUnit("kelvin", SI.KELVIN);
- database.addUnit("mole", SI.MOLE);
- database.addUnit("candela", SI.CANDELA);
- database.addUnit("bit", SI.BIT);
- database.addUnit("unit", SI.ONE);
+ database.addUnit("metre", Metric.METRE);
+ database.addUnit("kilogram", Metric.KILOGRAM);
+ database.addUnit("gram", Metric.KILOGRAM.dividedBy(1000));
+ database.addUnit("second", Metric.SECOND);
+ database.addUnit("ampere", Metric.AMPERE);
+ database.addUnit("kelvin", Metric.KELVIN);
+ database.addUnit("mole", Metric.MOLE);
+ database.addUnit("candela", Metric.CANDELA);
+ database.addUnit("bit", Metric.BIT);
+ database.addUnit("unit", Metric.ONE);
// nonlinear units - must be loaded manually
- database.addUnit("tempCelsius", SI.CELSIUS);
+ database.addUnit("tempCelsius", Metric.CELSIUS);
database.addUnit("tempFahrenheit", BritishImperial.FAHRENHEIT);
// load initial dimensions
- database.addDimension("LENGTH", SI.Dimensions.LENGTH);
- database.addDimension("MASS", SI.Dimensions.MASS);
- database.addDimension("TIME", SI.Dimensions.TIME);
- database.addDimension("TEMPERATURE", SI.Dimensions.TEMPERATURE);
+ database.addDimension("LENGTH", Metric.Dimensions.LENGTH);
+ database.addDimension("MASS", Metric.Dimensions.MASS);
+ database.addDimension("TIME", Metric.Dimensions.TIME);
+ database.addDimension("TEMPERATURE", Metric.Dimensions.TEMPERATURE);
}
/**
diff --git a/src/main/java/sevenUnits/unit/BaseUnit.java b/src/main/java/sevenUnits/unit/BaseUnit.java
index b1e30fb..ee2c277 100644
--- a/src/main/java/sevenUnits/unit/BaseUnit.java
+++ b/src/main/java/sevenUnits/unit/BaseUnit.java
@@ -75,7 +75,7 @@ public final class BaseUnit extends Unit {
*/
private BaseUnit(final BaseDimension dimension, final String primaryName,
final String symbol, final Set<String> otherNames) {
- super(primaryName, symbol, otherNames);
+ super(NameSymbol.of(primaryName, symbol, otherNames));
this.dimension = Objects.requireNonNull(dimension,
"dimension must not be null.");
}
diff --git a/src/main/java/sevenUnits/unit/BritishImperial.java b/src/main/java/sevenUnits/unit/BritishImperial.java
index 63da7f0..81a3f2a 100644
--- a/src/main/java/sevenUnits/unit/BritishImperial.java
+++ b/src/main/java/sevenUnits/unit/BritishImperial.java
@@ -48,7 +48,7 @@ public final class BritishImperial {
/**
* According to the International Yard and Pound of 1959, a yard is defined as exactly 0.9144 metres.
*/
- public static final LinearUnit YARD = SI.METRE.times(0.9144);
+ public static final LinearUnit YARD = Metric.METRE.times(0.9144);
public static final LinearUnit FOOT = YARD.dividedBy(3);
public static final LinearUnit INCH = FOOT.dividedBy(12);
public static final LinearUnit THOU = INCH.dividedBy(1000);
@@ -57,7 +57,7 @@ public final class BritishImperial {
public static final LinearUnit MILE = FURLONG.times(8);
public static final LinearUnit LEAGUE = MILE.times(3);
- public static final LinearUnit NAUTICAL_MILE = SI.METRE.times(1852);
+ public static final LinearUnit NAUTICAL_MILE = Metric.METRE.times(1852);
public static final LinearUnit CABLE = NAUTICAL_MILE.dividedBy(10);
public static final LinearUnit FATHOM = CABLE.dividedBy(100);
@@ -72,7 +72,7 @@ public final class BritishImperial {
* @since 2019-11-08
*/
public static final class Mass {
- public static final LinearUnit POUND = SI.GRAM.times(453.59237);
+ public static final LinearUnit POUND = Metric.GRAM.times(453.59237);
public static final LinearUnit OUNCE = POUND.dividedBy(16);
public static final LinearUnit DRACHM = POUND.dividedBy(256);
public static final LinearUnit GRAIN = POUND.dividedBy(7000);
@@ -80,7 +80,7 @@ public final class BritishImperial {
public static final LinearUnit QUARTER = STONE.times(2);
public static final LinearUnit HUNDREDWEIGHT = QUARTER.times(4);
public static final LinearUnit LONG_TON = HUNDREDWEIGHT.times(20);
- public static final LinearUnit SLUG = SI.KILOGRAM.times(14.59390294);
+ public static final LinearUnit SLUG = Metric.KILOGRAM.times(14.59390294);
}
/**
@@ -90,7 +90,7 @@ public final class BritishImperial {
* @since 2019-11-08
*/
public static final class Volume {
- public static final LinearUnit FLUID_OUNCE = SI.LITRE.withPrefix(SI.MILLI).times(28.4130625);
+ public static final LinearUnit FLUID_OUNCE = Metric.LITRE.withPrefix(Metric.MILLI).times(28.4130625);
public static final LinearUnit GILL = FLUID_OUNCE.times(5);
public static final LinearUnit PINT = FLUID_OUNCE.times(20);
public static final LinearUnit QUART = PINT.times(2);
@@ -104,13 +104,13 @@ public final class BritishImperial {
public static final LinearUnit ACRE_FOOT = Area.ACRE.times(Length.FOOT);
}
- public static final LinearUnit OUNCE_FORCE = Mass.OUNCE.times(SI.Constants.EARTH_GRAVITY);
- public static final LinearUnit POUND_FORCE = Mass.POUND.times(SI.Constants.EARTH_GRAVITY);
+ public static final LinearUnit OUNCE_FORCE = Mass.OUNCE.times(Metric.Constants.EARTH_GRAVITY);
+ public static final LinearUnit POUND_FORCE = Mass.POUND.times(Metric.Constants.EARTH_GRAVITY);
- public static final LinearUnit BRITISH_THERMAL_UNIT = SI.JOULE.times(1055.06);
- public static final LinearUnit CALORIE = SI.JOULE.times(4.184);
- public static final LinearUnit KILOCALORIE = SI.JOULE.times(4184);
+ public static final LinearUnit BRITISH_THERMAL_UNIT = Metric.JOULE.times(1055.06);
+ public static final LinearUnit CALORIE = Metric.JOULE.times(4.184);
+ public static final LinearUnit KILOCALORIE = Metric.JOULE.times(4184);
- public static final Unit FAHRENHEIT = Unit.fromConversionFunctions(SI.KELVIN.getBase(),
+ public static final Unit FAHRENHEIT = Unit.fromConversionFunctions(Metric.KELVIN.getBase(),
tempK -> tempK * 1.8 - 459.67, tempF -> (tempF + 459.67) / 1.8);
}
diff --git a/src/main/java/sevenUnits/unit/FunctionalUnit.java b/src/main/java/sevenUnits/unit/FunctionalUnit.java
index 7bacc9d..df457e4 100644
--- a/src/main/java/sevenUnits/unit/FunctionalUnit.java
+++ b/src/main/java/sevenUnits/unit/FunctionalUnit.java
@@ -19,7 +19,7 @@ package sevenUnits.unit;
import java.util.Objects;
import java.util.function.DoubleUnaryOperator;
-import sevenUnits.math.ObjectProduct;
+import sevenUnits.utils.ObjectProduct;
/**
* A unit that uses functional objects to convert to and from its base.
diff --git a/src/main/java/sevenUnits/unit/FunctionalUnitlike.java b/src/main/java/sevenUnits/unit/FunctionalUnitlike.java
index 61503e8..2ee9e19 100644
--- a/src/main/java/sevenUnits/unit/FunctionalUnitlike.java
+++ b/src/main/java/sevenUnits/unit/FunctionalUnitlike.java
@@ -19,7 +19,7 @@ package sevenUnits.unit;
import java.util.function.DoubleFunction;
import java.util.function.ToDoubleFunction;
-import sevenUnits.math.ObjectProduct;
+import sevenUnits.utils.ObjectProduct;
/**
* A unitlike form that converts using two conversion functions.
diff --git a/src/main/java/sevenUnits/unit/LinearUnit.java b/src/main/java/sevenUnits/unit/LinearUnit.java
index 7c46443..25c2e2e 100644
--- a/src/main/java/sevenUnits/unit/LinearUnit.java
+++ b/src/main/java/sevenUnits/unit/LinearUnit.java
@@ -18,9 +18,9 @@ package sevenUnits.unit;
import java.util.Objects;
-import sevenUnits.math.DecimalComparison;
-import sevenUnits.math.ObjectProduct;
-import sevenUnits.math.UncertainDouble;
+import sevenUnits.utils.DecimalComparison;
+import sevenUnits.utils.ObjectProduct;
+import sevenUnits.utils.UncertainDouble;
/**
* A unit that can be expressed as a product of its base and a number. For
diff --git a/src/main/java/sevenUnits/unit/LinearUnitValue.java b/src/main/java/sevenUnits/unit/LinearUnitValue.java
index 687a8b4..a36d568 100644
--- a/src/main/java/sevenUnits/unit/LinearUnitValue.java
+++ b/src/main/java/sevenUnits/unit/LinearUnitValue.java
@@ -19,8 +19,8 @@ package sevenUnits.unit;
import java.util.Objects;
import java.util.Optional;
-import sevenUnits.math.DecimalComparison;
-import sevenUnits.math.UncertainDouble;
+import sevenUnits.utils.DecimalComparison;
+import sevenUnits.utils.UncertainDouble;
/**
* A possibly uncertain value expressed in a linear unit.
@@ -32,7 +32,7 @@ import sevenUnits.math.UncertainDouble;
* @since 2020-07-26
*/
public final class LinearUnitValue {
- public static final LinearUnitValue ONE = getExact(SI.ONE, 1);
+ public static final LinearUnitValue ONE = getExact(Metric.ONE, 1);
/**
* Gets an exact {@code LinearUnitValue}
diff --git a/src/main/java/sevenUnits/unit/SI.java b/src/main/java/sevenUnits/unit/Metric.java
index e0e5a54..3c4d291 100644
--- a/src/main/java/sevenUnits/unit/SI.java
+++ b/src/main/java/sevenUnits/unit/Metric.java
@@ -18,7 +18,7 @@ package sevenUnits.unit;
import java.util.Set;
-import sevenUnits.math.ObjectProduct;
+import sevenUnits.utils.ObjectProduct;
/**
* All of the units, prefixes and dimensions that are used by the SI, as well as
@@ -36,7 +36,7 @@ import sevenUnits.math.ObjectProduct;
* @author Adrien Hopkins
* @since 2019-10-16
*/
-public final class SI {
+public final class Metric {
/// dimensions used by SI units
// base dimensions, as BaseDimensions
public static final class BaseDimensions {
@@ -402,57 +402,57 @@ public final class SI {
.withName(NameSymbol.of("exbi", "Ei"));
// a few prefixed units
- public static final LinearUnit MICROMETRE = SI.METRE.withPrefix(SI.MICRO);
- public static final LinearUnit MILLIMETRE = SI.METRE.withPrefix(SI.MILLI);
- public static final LinearUnit KILOMETRE = SI.METRE.withPrefix(SI.KILO);
- public static final LinearUnit MEGAMETRE = SI.METRE.withPrefix(SI.MEGA);
+ public static final LinearUnit MICROMETRE = Metric.METRE.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLIMETRE = Metric.METRE.withPrefix(Metric.MILLI);
+ public static final LinearUnit KILOMETRE = Metric.METRE.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGAMETRE = Metric.METRE.withPrefix(Metric.MEGA);
- public static final LinearUnit MICROLITRE = SI.LITRE.withPrefix(SI.MICRO);
- public static final LinearUnit MILLILITRE = SI.LITRE.withPrefix(SI.MILLI);
- public static final LinearUnit KILOLITRE = SI.LITRE.withPrefix(SI.KILO);
- public static final LinearUnit MEGALITRE = SI.LITRE.withPrefix(SI.MEGA);
+ public static final LinearUnit MICROLITRE = Metric.LITRE.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLILITRE = Metric.LITRE.withPrefix(Metric.MILLI);
+ public static final LinearUnit KILOLITRE = Metric.LITRE.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGALITRE = Metric.LITRE.withPrefix(Metric.MEGA);
- public static final LinearUnit MICROSECOND = SI.SECOND.withPrefix(SI.MICRO);
- public static final LinearUnit MILLISECOND = SI.SECOND.withPrefix(SI.MILLI);
- public static final LinearUnit KILOSECOND = SI.SECOND.withPrefix(SI.KILO);
- public static final LinearUnit MEGASECOND = SI.SECOND.withPrefix(SI.MEGA);
+ public static final LinearUnit MICROSECOND = Metric.SECOND.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLISECOND = Metric.SECOND.withPrefix(Metric.MILLI);
+ public static final LinearUnit KILOSECOND = Metric.SECOND.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGASECOND = Metric.SECOND.withPrefix(Metric.MEGA);
- public static final LinearUnit MICROGRAM = SI.GRAM.withPrefix(SI.MICRO);
- public static final LinearUnit MILLIGRAM = SI.GRAM.withPrefix(SI.MILLI);
- public static final LinearUnit MEGAGRAM = SI.GRAM.withPrefix(SI.MEGA);
+ public static final LinearUnit MICROGRAM = Metric.GRAM.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLIGRAM = Metric.GRAM.withPrefix(Metric.MILLI);
+ public static final LinearUnit MEGAGRAM = Metric.GRAM.withPrefix(Metric.MEGA);
- public static final LinearUnit MICRONEWTON = SI.NEWTON.withPrefix(SI.MICRO);
- public static final LinearUnit MILLINEWTON = SI.NEWTON.withPrefix(SI.MILLI);
- public static final LinearUnit KILONEWTON = SI.NEWTON.withPrefix(SI.KILO);
- public static final LinearUnit MEGANEWTON = SI.NEWTON.withPrefix(SI.MEGA);
+ public static final LinearUnit MICRONEWTON = Metric.NEWTON.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLINEWTON = Metric.NEWTON.withPrefix(Metric.MILLI);
+ public static final LinearUnit KILONEWTON = Metric.NEWTON.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGANEWTON = Metric.NEWTON.withPrefix(Metric.MEGA);
- public static final LinearUnit MICROJOULE = SI.JOULE.withPrefix(SI.MICRO);
- public static final LinearUnit MILLIJOULE = SI.JOULE.withPrefix(SI.MILLI);
- public static final LinearUnit KILOJOULE = SI.JOULE.withPrefix(SI.KILO);
- public static final LinearUnit MEGAJOULE = SI.JOULE.withPrefix(SI.MEGA);
+ public static final LinearUnit MICROJOULE = Metric.JOULE.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLIJOULE = Metric.JOULE.withPrefix(Metric.MILLI);
+ public static final LinearUnit KILOJOULE = Metric.JOULE.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGAJOULE = Metric.JOULE.withPrefix(Metric.MEGA);
- public static final LinearUnit MICROWATT = SI.WATT.withPrefix(SI.MICRO);
- public static final LinearUnit MILLIWATT = SI.WATT.withPrefix(SI.MILLI);
- public static final LinearUnit KILOWATT = SI.WATT.withPrefix(SI.KILO);
- public static final LinearUnit MEGAWATT = SI.WATT.withPrefix(SI.MEGA);
+ public static final LinearUnit MICROWATT = Metric.WATT.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLIWATT = Metric.WATT.withPrefix(Metric.MILLI);
+ public static final LinearUnit KILOWATT = Metric.WATT.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGAWATT = Metric.WATT.withPrefix(Metric.MEGA);
- public static final LinearUnit MICROCOULOMB = SI.COULOMB
- .withPrefix(SI.MICRO);
- public static final LinearUnit MILLICOULOMB = SI.COULOMB
- .withPrefix(SI.MILLI);
- public static final LinearUnit KILOCOULOMB = SI.COULOMB.withPrefix(SI.KILO);
- public static final LinearUnit MEGACOULOMB = SI.COULOMB.withPrefix(SI.MEGA);
+ public static final LinearUnit MICROCOULOMB = Metric.COULOMB
+ .withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLICOULOMB = Metric.COULOMB
+ .withPrefix(Metric.MILLI);
+ public static final LinearUnit KILOCOULOMB = Metric.COULOMB.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGACOULOMB = Metric.COULOMB.withPrefix(Metric.MEGA);
- public static final LinearUnit MICROAMPERE = SI.AMPERE.withPrefix(SI.MICRO);
- public static final LinearUnit MILLIAMPERE = SI.AMPERE.withPrefix(SI.MILLI);
+ public static final LinearUnit MICROAMPERE = Metric.AMPERE.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLIAMPERE = Metric.AMPERE.withPrefix(Metric.MILLI);
- public static final LinearUnit MICROVOLT = SI.VOLT.withPrefix(SI.MICRO);
- public static final LinearUnit MILLIVOLT = SI.VOLT.withPrefix(SI.MILLI);
- public static final LinearUnit KILOVOLT = SI.VOLT.withPrefix(SI.KILO);
- public static final LinearUnit MEGAVOLT = SI.VOLT.withPrefix(SI.MEGA);
+ public static final LinearUnit MICROVOLT = Metric.VOLT.withPrefix(Metric.MICRO);
+ public static final LinearUnit MILLIVOLT = Metric.VOLT.withPrefix(Metric.MILLI);
+ public static final LinearUnit KILOVOLT = Metric.VOLT.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGAVOLT = Metric.VOLT.withPrefix(Metric.MEGA);
- public static final LinearUnit KILOOHM = SI.OHM.withPrefix(SI.KILO);
- public static final LinearUnit MEGAOHM = SI.OHM.withPrefix(SI.MEGA);
+ public static final LinearUnit KILOOHM = Metric.OHM.withPrefix(Metric.KILO);
+ public static final LinearUnit MEGAOHM = Metric.OHM.withPrefix(Metric.MEGA);
// sets of prefixes
public static final Set<UnitPrefix> ALL_PREFIXES = Set.of(DEKA, HECTO, KILO,
@@ -473,7 +473,7 @@ public final class SI {
MILLI, MICRO, NANO, PICO, FEMTO, ATTO, ZEPTO, YOCTO);
// You may NOT get SI instances!
- private SI() {
+ private Metric() {
throw new AssertionError();
}
}
diff --git a/src/main/java/sevenUnits/unit/MultiUnit.java b/src/main/java/sevenUnits/unit/MultiUnit.java
index 014e055..83cdb03 100644
--- a/src/main/java/sevenUnits/unit/MultiUnit.java
+++ b/src/main/java/sevenUnits/unit/MultiUnit.java
@@ -20,7 +20,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import sevenUnits.math.ObjectProduct;
+import sevenUnits.utils.ObjectProduct;
/**
* A combination of units, like "5 foot + 7 inch". All but the last units should
diff --git a/src/main/java/sevenUnits/unit/USCustomary.java b/src/main/java/sevenUnits/unit/USCustomary.java
index 76356c0..459071f 100644
--- a/src/main/java/sevenUnits/unit/USCustomary.java
+++ b/src/main/java/sevenUnits/unit/USCustomary.java
@@ -52,7 +52,7 @@ public final class USCustomary {
public static final LinearUnit YARD = BritishImperial.Length.YARD;
public static final LinearUnit MILE = BritishImperial.Length.MILE;
- public static final LinearUnit SURVEY_FOOT = SI.METRE.times(1200.0 / 3937.0);
+ public static final LinearUnit SURVEY_FOOT = Metric.METRE.times(1200.0 / 3937.0);
public static final LinearUnit SURVEY_LINK = SURVEY_FOOT.times(33.0 / 50.0);
public static final LinearUnit SURVEY_ROD = SURVEY_FOOT.times(16.5);
public static final LinearUnit SURVEY_CHAIN = SURVEY_ROD.times(4);
@@ -97,7 +97,7 @@ public final class USCustomary {
public static final LinearUnit CUBIC_YARD = Length.YARD.toExponent(3);
public static final LinearUnit ACRE_FOOT = Area.ACRE.times(Length.FOOT);
- public static final LinearUnit MINIM = SI.LITRE.withPrefix(SI.MICRO).times(61.611519921875);
+ public static final LinearUnit MINIM = Metric.LITRE.withPrefix(Metric.MICRO).times(61.611519921875);
public static final LinearUnit FLUID_DRAM = MINIM.times(60);
public static final LinearUnit TEASPOON = MINIM.times(80);
public static final LinearUnit TABLESPOON = TEASPOON.times(3);
@@ -112,7 +112,7 @@ public final class USCustomary {
public static final LinearUnit OIL_BARREL = GALLON.times(42);
public static final LinearUnit HOGSHEAD = GALLON.times(63);
- public static final LinearUnit DRY_PINT = SI.LITRE.times(0.5506104713575);
+ public static final LinearUnit DRY_PINT = Metric.LITRE.times(0.5506104713575);
public static final LinearUnit DRY_QUART = DRY_PINT.times(2);
public static final LinearUnit DRY_GALLON = DRY_QUART.times(4);
public static final LinearUnit PECK = DRY_GALLON.times(2);
@@ -128,7 +128,7 @@ public final class USCustomary {
public static final LinearUnit KILOCALORIE = BritishImperial.KILOCALORIE;
public static final LinearUnit FOOT_POUND = POUND_FORCE.times(Length.FOOT);
- public static final LinearUnit HORSEPOWER = Length.FOOT.times(POUND_FORCE).dividedBy(SI.MINUTE).times(33000);
+ public static final LinearUnit HORSEPOWER = Length.FOOT.times(POUND_FORCE).dividedBy(Metric.MINUTE).times(33000);
public static final LinearUnit POUND_PER_SQUARE_INCH = POUND_FORCE.dividedBy(Length.INCH.toExponent(2));
public static final Unit FAHRENHEIT = BritishImperial.FAHRENHEIT;
diff --git a/src/main/java/sevenUnits/unit/Unit.java b/src/main/java/sevenUnits/unit/Unit.java
index 1e875af..005b6f7 100644
--- a/src/main/java/sevenUnits/unit/Unit.java
+++ b/src/main/java/sevenUnits/unit/Unit.java
@@ -17,14 +17,12 @@
package sevenUnits.unit;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Objects;
-import java.util.Set;
import java.util.function.DoubleUnaryOperator;
-import sevenUnits.math.DecimalComparison;
-import sevenUnits.math.ObjectProduct;
+import sevenUnits.utils.DecimalComparison;
+import sevenUnits.utils.ObjectProduct;
/**
* A unit that is composed of base units.
@@ -110,6 +108,19 @@ public abstract class Unit implements Nameable {
private transient ObjectProduct<BaseDimension> dimension = null;
/**
+ * A constructor that constructs {@code BaseUnit} instances.
+ *
+ * @since 2019-10-16
+ */
+ Unit(final NameSymbol nameSymbol) {
+ if (this instanceof BaseUnit) {
+ this.unitBase = ObjectProduct.oneOf((BaseUnit) this);
+ } else
+ throw new AssertionError();
+ this.nameSymbol = nameSymbol;
+ }
+
+ /**
* Creates the {@code Unit}.
*
* @param unitBase base of unit
@@ -117,28 +128,13 @@ public abstract class Unit implements Nameable {
* @since 2019-10-16
* @throws NullPointerException if unitBase or ns is null
*/
- Unit(ObjectProduct<BaseUnit> unitBase, NameSymbol ns) {
+ protected Unit(ObjectProduct<BaseUnit> unitBase, NameSymbol ns) {
this.unitBase = Objects.requireNonNull(unitBase,
"unitBase may not be null");
this.nameSymbol = Objects.requireNonNull(ns, "ns may not be null");
}
/**
- * A constructor that constructs {@code BaseUnit} instances.
- *
- * @since 2019-10-16
- */
- Unit(final String primaryName, final String symbol,
- final Set<String> otherNames) {
- if (this instanceof BaseUnit) {
- this.unitBase = ObjectProduct.oneOf((BaseUnit) this);
- } else
- throw new AssertionError();
- this.nameSymbol = NameSymbol.of(primaryName, symbol,
- new HashSet<>(otherNames));
- }
-
- /**
* @return this unit as a {@link Unitlike}
* @since 2020-09-07
*/
@@ -342,7 +338,7 @@ public abstract class Unit implements Nameable {
// second condition - check that
for (final BaseUnit b : linear.getBase().getBaseSet()) {
- if (!SI.BaseUnits.BASE_UNITS.contains(b))
+ if (!Metric.BaseUnits.BASE_UNITS.contains(b))
return false;
}
diff --git a/src/main/java/sevenUnits/unit/UnitDatabase.java b/src/main/java/sevenUnits/unit/UnitDatabase.java
index 1960229..b45d9cf 100644
--- a/src/main/java/sevenUnits/unit/UnitDatabase.java
+++ b/src/main/java/sevenUnits/unit/UnitDatabase.java
@@ -44,11 +44,11 @@ import java.util.function.Predicate;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import sevenUnits.math.ConditionalExistenceCollections;
-import sevenUnits.math.DecimalComparison;
-import sevenUnits.math.ExpressionParser;
-import sevenUnits.math.ObjectProduct;
-import sevenUnits.math.UncertainDouble;
+import sevenUnits.utils.ConditionalExistenceCollections;
+import sevenUnits.utils.DecimalComparison;
+import sevenUnits.utils.ExpressionParser;
+import sevenUnits.utils.ObjectProduct;
+import sevenUnits.utils.UncertainDouble;
/**
* A database of units, prefixes and dimensions, and their names.
@@ -1116,7 +1116,7 @@ public final class UnitDatabase {
private static final LinearUnit exponentiateUnits(final LinearUnit base,
final LinearUnit exponentUnit) {
// exponent function - first check if o2 is a number,
- if (exponentUnit.getBase().equals(SI.ONE.getBase())) {
+ if (exponentUnit.getBase().equals(Metric.ONE.getBase())) {
// then check if it is an integer,
final double exponent = exponentUnit.getConversionFactor();
if (DecimalComparison.equals(exponent % 1, 0))
@@ -1142,7 +1142,7 @@ public final class UnitDatabase {
private static final LinearUnitValue exponentiateUnitValues(
final LinearUnitValue base, final LinearUnitValue exponentValue) {
// exponent function - first check if o2 is a number,
- if (exponentValue.canConvertTo(SI.ONE)) {
+ if (exponentValue.canConvertTo(Metric.ONE)) {
// then check if it is an integer,
final double exponent = exponentValue.getValueExact();
if (DecimalComparison.equals(exponent % 1, 0))
@@ -1676,7 +1676,7 @@ public final class UnitDatabase {
final BigDecimal number = new BigDecimal(name);
final double uncertainty = Math.pow(10, -number.scale());
- return LinearUnitValue.of(SI.ONE,
+ return LinearUnitValue.of(Metric.ONE,
UncertainDouble.of(number.doubleValue(), uncertainty));
} catch (final NumberFormatException e) {
return LinearUnitValue.getExact(this.getLinearUnit(name), 1);
@@ -1786,7 +1786,7 @@ public final class UnitDatabase {
public Unit getUnit(final String name) {
try {
final double value = Double.parseDouble(name);
- return SI.ONE.times(value);
+ return Metric.ONE.times(value);
} catch (final NumberFormatException e) {
final Unit unit = this.units.get(name);
if (unit == null)
diff --git a/src/main/java/sevenUnits/unit/UnitPrefix.java b/src/main/java/sevenUnits/unit/UnitPrefix.java
index e4a27bd..308f4b0 100644
--- a/src/main/java/sevenUnits/unit/UnitPrefix.java
+++ b/src/main/java/sevenUnits/unit/UnitPrefix.java
@@ -20,7 +20,7 @@ import java.util.Objects;
import java.util.Optional;
import java.util.Set;
-import sevenUnits.math.DecimalComparison;
+import sevenUnits.utils.DecimalComparison;
/**
* A prefix that can be applied to a {@code LinearUnit} to multiply it by some value
diff --git a/src/main/java/sevenUnits/unit/Unitlike.java b/src/main/java/sevenUnits/unit/Unitlike.java
index fd361b6..d2dcbbb 100644
--- a/src/main/java/sevenUnits/unit/Unitlike.java
+++ b/src/main/java/sevenUnits/unit/Unitlike.java
@@ -22,7 +22,7 @@ import java.util.Objects;
import java.util.function.DoubleFunction;
import java.util.function.ToDoubleFunction;
-import sevenUnits.math.ObjectProduct;
+import sevenUnits.utils.ObjectProduct;
/**
* An object that can convert a value between multiple forms (instances of the
diff --git a/src/main/java/sevenUnits/math/ConditionalExistenceCollections.java b/src/main/java/sevenUnits/utils/ConditionalExistenceCollections.java
index 5ce1bd7..2adb579 100644
--- a/src/main/java/sevenUnits/math/ConditionalExistenceCollections.java
+++ b/src/main/java/sevenUnits/utils/ConditionalExistenceCollections.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package sevenUnits.math;
+package sevenUnits.utils;
import java.util.AbstractCollection;
import java.util.AbstractMap;
diff --git a/src/main/java/sevenUnits/math/DecimalComparison.java b/src/main/java/sevenUnits/utils/DecimalComparison.java
index 24a9b2f..a5cbbaa 100644
--- a/src/main/java/sevenUnits/math/DecimalComparison.java
+++ b/src/main/java/sevenUnits/utils/DecimalComparison.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package sevenUnits.math;
+package sevenUnits.utils;
import java.math.BigDecimal;
diff --git a/src/main/java/sevenUnits/math/ExpressionParser.java b/src/main/java/sevenUnits/utils/ExpressionParser.java
index 5c8183b..1d3d44d 100644
--- a/src/main/java/sevenUnits/math/ExpressionParser.java
+++ b/src/main/java/sevenUnits/utils/ExpressionParser.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package sevenUnits.math;
+package sevenUnits.utils;
import java.util.ArrayDeque;
import java.util.ArrayList;
diff --git a/src/main/java/sevenUnits/math/ObjectProduct.java b/src/main/java/sevenUnits/utils/ObjectProduct.java
index db95fd4..1dacb7d 100644
--- a/src/main/java/sevenUnits/math/ObjectProduct.java
+++ b/src/main/java/sevenUnits/utils/ObjectProduct.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package sevenUnits.math;
+package sevenUnits.utils;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/src/main/java/sevenUnits/math/UncertainDouble.java b/src/main/java/sevenUnits/utils/UncertainDouble.java
index b81bb79..8fe4b31 100644
--- a/src/main/java/sevenUnits/math/UncertainDouble.java
+++ b/src/main/java/sevenUnits/utils/UncertainDouble.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package sevenUnits.math;
+package sevenUnits.utils;
import java.math.BigDecimal;
import java.math.RoundingMode;
diff --git a/src/main/java/sevenUnits/math/package-info.java b/src/main/java/sevenUnits/utils/package-info.java
index 62f72cd..350c62d 100644
--- a/src/main/java/sevenUnits/math/package-info.java
+++ b/src/main/java/sevenUnits/utils/package-info.java
@@ -1,5 +1,5 @@
/**
- * Copyright (C) 2019 Adrien Hopkins
+ * Copyright (C) 2018-2020 Adrien Hopkins
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
@@ -15,10 +15,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
- * Supplementary classes that are not related to units, but are necessary for their function.
+ * Supplementary classes that are not related to units, but are necessary for
+ * their function.
*
* @author Adrien Hopkins
* @since 2019-03-14
* @since v0.2.0
*/
-package sevenUnits.math; \ No newline at end of file
+package sevenUnits.utils; \ No newline at end of file
diff --git a/src/test/java/sevenUnits/unit/MultiUnitTest.java b/src/test/java/sevenUnits/unit/MultiUnitTest.java
index 82722af..d632118 100644
--- a/src/test/java/sevenUnits/unit/MultiUnitTest.java
+++ b/src/test/java/sevenUnits/unit/MultiUnitTest.java
@@ -27,7 +27,7 @@ import org.junit.jupiter.api.Test;
import sevenUnits.unit.BritishImperial;
import sevenUnits.unit.MultiUnit;
-import sevenUnits.unit.SI;
+import sevenUnits.unit.Metric;
/**
* Tests related to the {@code MultiUnit}.
@@ -42,7 +42,7 @@ class MultiUnitTest {
final MultiUnit footInch = MultiUnit.of(BritishImperial.Length.FOOT,
BritishImperial.Length.INCH);
- assertEquals(1702.0, footInch.convertTo(SI.METRE.withPrefix(SI.MILLI),
+ assertEquals(1702.0, footInch.convertTo(Metric.METRE.withPrefix(Metric.MILLI),
Arrays.asList(5.0, 7.0)), 1.0);
for (int i = 0; i < 1000; i++) {
@@ -50,7 +50,7 @@ class MultiUnitTest {
final double inches = rng.nextDouble() * 12;
final double millimetres = feet * 304.8 + inches * 25.4;
- final List<Double> feetAndInches = SI.METRE.withPrefix(SI.MILLI)
+ final List<Double> feetAndInches = Metric.METRE.withPrefix(Metric.MILLI)
.convertTo(footInch, millimetres);
assertEquals(feet, feetAndInches.get(0), 1e-10);
assertEquals(inches, feetAndInches.get(1), 1e-10);
diff --git a/src/test/java/sevenUnits/unit/UnitDatabaseTest.java b/src/test/java/sevenUnits/unit/UnitDatabaseTest.java
index c706b5c..1d5e503 100644
--- a/src/test/java/sevenUnits/unit/UnitDatabaseTest.java
+++ b/src/test/java/sevenUnits/unit/UnitDatabaseTest.java
@@ -33,7 +33,7 @@ import org.junit.jupiter.api.Test;
import sevenUnits.unit.LinearUnit;
import sevenUnits.unit.NameSymbol;
-import sevenUnits.unit.SI;
+import sevenUnits.unit.Metric;
import sevenUnits.unit.Unit;
import sevenUnits.unit.UnitDatabase;
import sevenUnits.unit.UnitPrefix;
@@ -48,18 +48,18 @@ import sevenUnits.unit.UnitPrefix;
*/
class UnitDatabaseTest {
// some linear units and one nonlinear
- private static final Unit U = SI.METRE;
- private static final Unit V = SI.KILOGRAM;
- private static final Unit W = SI.SECOND;
+ private static final Unit U = Metric.METRE;
+ private static final Unit V = Metric.KILOGRAM;
+ private static final Unit W = Metric.SECOND;
// used for testing expressions
// J = U^2 * V / W^2
- private static final LinearUnit J = SI.KILOGRAM.times(SI.METRE.toExponent(2))
- .dividedBy(SI.SECOND.toExponent(2));
- private static final LinearUnit K = SI.KELVIN;
+ private static final LinearUnit J = Metric.KILOGRAM.times(Metric.METRE.toExponent(2))
+ .dividedBy(Metric.SECOND.toExponent(2));
+ private static final LinearUnit K = Metric.KELVIN;
private static final Unit NONLINEAR = Unit
- .fromConversionFunctions(SI.METRE.getBase(), o -> o + 1, o -> o - 1);
+ .fromConversionFunctions(Metric.METRE.getBase(), o -> o + 1, o -> o - 1);
// make the prefix values prime so I can tell which multiplications were made
private static final UnitPrefix A = UnitPrefix.valueOf(2)
diff --git a/src/test/java/sevenUnits/unit/UnitTest.java b/src/test/java/sevenUnits/unit/UnitTest.java
index d216ae8..a980054 100644
--- a/src/test/java/sevenUnits/unit/UnitTest.java
+++ b/src/test/java/sevenUnits/unit/UnitTest.java
@@ -26,13 +26,13 @@ import java.util.concurrent.ThreadLocalRandom;
import org.junit.jupiter.api.Test;
-import sevenUnits.math.DecimalComparison;
import sevenUnits.unit.LinearUnit;
import sevenUnits.unit.LinearUnitValue;
import sevenUnits.unit.NameSymbol;
-import sevenUnits.unit.SI;
+import sevenUnits.unit.Metric;
import sevenUnits.unit.Unit;
import sevenUnits.unit.UnitValue;
+import sevenUnits.utils.DecimalComparison;
/**
* Testing the various Unit classes. This is NOT part of this program's public
@@ -48,19 +48,19 @@ class UnitTest {
@Test
public void testAdditionAndSubtraction() {
- final LinearUnit inch = SI.METRE.times(0.0254)
+ final LinearUnit inch = Metric.METRE.times(0.0254)
.withName(NameSymbol.of("inch", "in"));
- final LinearUnit foot = SI.METRE.times(0.3048)
+ final LinearUnit foot = Metric.METRE.times(0.3048)
.withName(NameSymbol.of("foot", "ft"));
- assertEquals(inch.plus(foot), SI.METRE.times(0.3302));
- assertEquals(foot.minus(inch), SI.METRE.times(0.2794));
+ assertEquals(inch.plus(foot), Metric.METRE.times(0.3302));
+ assertEquals(foot.minus(inch), Metric.METRE.times(0.2794));
// test with LinearUnitValue
- final LinearUnitValue value1 = LinearUnitValue.getExact(SI.METRE, 15);
+ final LinearUnitValue value1 = LinearUnitValue.getExact(Metric.METRE, 15);
final LinearUnitValue value2 = LinearUnitValue.getExact(foot, 120);
- final LinearUnitValue value3 = LinearUnitValue.getExact(SI.METRE, 0.5);
- final LinearUnitValue value4 = LinearUnitValue.getExact(SI.KILOGRAM, 60);
+ final LinearUnitValue value3 = LinearUnitValue.getExact(Metric.METRE, 0.5);
+ final LinearUnitValue value4 = LinearUnitValue.getExact(Metric.KILOGRAM, 60);
// make sure addition is done correctly
assertEquals(51.576, value1.plus(value2).getValueExact(), 0.001);
@@ -70,8 +70,8 @@ class UnitTest {
// make sure addition uses the correct unit, and is still associative
// (ignoring floating-point rounding errors)
- assertEquals(SI.METRE, value1.plus(value2).getUnit());
- assertEquals(SI.METRE, value1.plus(value2).plus(value3).getUnit());
+ assertEquals(Metric.METRE, value1.plus(value2).getUnit());
+ assertEquals(Metric.METRE, value1.plus(value2).plus(value3).getUnit());
assertEquals(foot, value2.plus(value1).getUnit());
assertTrue(value1.plus(value2).equals(value2.plus(value1), true));
@@ -81,7 +81,7 @@ class UnitTest {
@Test
public void testConversion() {
- final LinearUnit metre = SI.METRE;
+ final LinearUnit metre = Metric.METRE;
final Unit inch = metre.times(0.0254);
final UnitValue value = UnitValue.of(inch, 75);
@@ -97,7 +97,7 @@ class UnitTest {
final double expected = testValue * conversionFactor;
// test
- final Unit unit = SI.METRE.times(conversionFactor);
+ final Unit unit = Metric.METRE.times(conversionFactor);
final double actual = unit.convertToBase(testValue);
assertEquals(actual, expected,
@@ -107,17 +107,17 @@ class UnitTest {
@Test
public void testEquals() {
- final LinearUnit metre = SI.METRE;
- final Unit meter = SI.BaseUnits.METRE.asLinearUnit();
+ final LinearUnit metre = Metric.METRE;
+ final Unit meter = Metric.BaseUnits.METRE.asLinearUnit();
assertEquals(metre, meter);
}
@Test
public void testIsMetric() {
- final Unit metre = SI.METRE;
- final Unit megasecond = SI.SECOND.withPrefix(SI.MEGA);
- final Unit hour = SI.HOUR;
+ final Unit metre = Metric.METRE;
+ final Unit megasecond = Metric.SECOND.withPrefix(Metric.MEGA);
+ final Unit hour = Metric.HOUR;
assertTrue(metre.isMetric());
assertTrue(megasecond.isMetric());
@@ -127,26 +127,26 @@ class UnitTest {
@Test
public void testMultiplicationAndDivision() {
// test unit-times-unit multiplication
- final LinearUnit generatedJoule = SI.KILOGRAM
- .times(SI.METRE.toExponent(2)).dividedBy(SI.SECOND.toExponent(2));
- final LinearUnit actualJoule = SI.JOULE;
+ final LinearUnit generatedJoule = Metric.KILOGRAM
+ .times(Metric.METRE.toExponent(2)).dividedBy(Metric.SECOND.toExponent(2));
+ final LinearUnit actualJoule = Metric.JOULE;
assertEquals(generatedJoule, actualJoule);
// test multiplication by conversion factors
- final LinearUnit kilometre = SI.METRE.times(1000);
- final LinearUnit hour = SI.SECOND.times(3600);
+ final LinearUnit kilometre = Metric.METRE.times(1000);
+ final LinearUnit hour = Metric.SECOND.times(3600);
final LinearUnit generatedKPH = kilometre.dividedBy(hour);
- final LinearUnit actualKPH = SI.METRE.dividedBy(SI.SECOND).dividedBy(3.6);
+ final LinearUnit actualKPH = Metric.METRE.dividedBy(Metric.SECOND).dividedBy(3.6);
assertEquals(generatedKPH, actualKPH);
}
@Test
public void testPrefixes() {
- final LinearUnit generatedKilometre = SI.METRE.withPrefix(SI.KILO);
- final LinearUnit actualKilometre = SI.METRE.times(1000);
+ final LinearUnit generatedKilometre = Metric.METRE.withPrefix(Metric.KILO);
+ final LinearUnit actualKilometre = Metric.METRE.times(1000);
assertEquals(generatedKilometre, actualKilometre);
}
diff --git a/src/test/java/sevenUnits/math/ConditionalExistenceCollectionsTest.java b/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java
index a35dc5a..46afe77 100644
--- a/src/test/java/sevenUnits/math/ConditionalExistenceCollectionsTest.java
+++ b/src/test/java/sevenUnits/utils/ConditionalExistenceCollectionsTest.java
@@ -14,7 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package sevenUnits.math;
+package sevenUnits.utils;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
@@ -31,8 +31,8 @@ import java.util.NoSuchElementException;
import org.junit.jupiter.api.Test;
-import sevenUnits.math.ConditionalExistenceCollections;
-import sevenUnits.math.ConditionalExistenceCollections.ConditionalExistenceIterator;
+import sevenUnits.utils.ConditionalExistenceCollections;
+import sevenUnits.utils.ConditionalExistenceCollections.ConditionalExistenceIterator;
/**
* Tests the {@link #ConditionalExistenceCollections}.
diff --git a/src/test/java/sevenUnits/math/ExpressionParserTest.java b/src/test/java/sevenUnits/utils/ExpressionParserTest.java
index 4801233..29648ee 100644
--- a/src/test/java/sevenUnits/math/ExpressionParserTest.java
+++ b/src/test/java/sevenUnits/utils/ExpressionParserTest.java
@@ -14,13 +14,13 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package sevenUnits.math;
+package sevenUnits.utils;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
-import sevenUnits.math.ExpressionParser;
+import sevenUnits.utils.ExpressionParser;
/**
* A test for the {@code ExpressionParser} class. This is NOT part of this program's public API.
@@ -36,7 +36,7 @@ class ExpressionParserTest {
.addBinaryOperator("^", (o1, o2) -> (int) Math.pow(o1, o2), 2).build();
/**
- * Test method for {@link sevenUnits.math.ExpressionParser#parseExpression(java.lang.String)}.
+ * Test method for {@link sevenUnits.utils.ExpressionParser#parseExpression(java.lang.String)}.
*/
@Test
public void testParseExpression() {
diff --git a/src/test/java/sevenUnits/math/ObjectProductTest.java b/src/test/java/sevenUnits/utils/ObjectProductTest.java
index 1734f26..13fd7ec 100644
--- a/src/test/java/sevenUnits/math/ObjectProductTest.java
+++ b/src/test/java/sevenUnits/utils/ObjectProductTest.java
@@ -14,23 +14,23 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
-package sevenUnits.math;
+package sevenUnits.utils;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
-import static sevenUnits.unit.SI.Dimensions.AREA;
-import static sevenUnits.unit.SI.Dimensions.ENERGY;
-import static sevenUnits.unit.SI.Dimensions.LENGTH;
-import static sevenUnits.unit.SI.Dimensions.MASS;
-import static sevenUnits.unit.SI.Dimensions.MASS_DENSITY;
-import static sevenUnits.unit.SI.Dimensions.QUANTITY;
-import static sevenUnits.unit.SI.Dimensions.TIME;
-import static sevenUnits.unit.SI.Dimensions.VOLUME;
+import static sevenUnits.unit.Metric.Dimensions.AREA;
+import static sevenUnits.unit.Metric.Dimensions.ENERGY;
+import static sevenUnits.unit.Metric.Dimensions.LENGTH;
+import static sevenUnits.unit.Metric.Dimensions.MASS;
+import static sevenUnits.unit.Metric.Dimensions.MASS_DENSITY;
+import static sevenUnits.unit.Metric.Dimensions.QUANTITY;
+import static sevenUnits.unit.Metric.Dimensions.TIME;
+import static sevenUnits.unit.Metric.Dimensions.VOLUME;
import org.junit.jupiter.api.Test;
-import sevenUnits.math.ObjectProduct;
-import sevenUnits.unit.SI;
+import sevenUnits.unit.Metric;
+import sevenUnits.utils.ObjectProduct;
/**
* Tests for {@link ObjectProduct} using BaseDimension as a test object. This is NOT part of this program's public API.
@@ -60,8 +60,8 @@ class ObjectProductTest {
*/
@Test
public void testExponents() {
- assertEquals(1, LENGTH.getExponent(SI.BaseDimensions.LENGTH));
- assertEquals(3, VOLUME.getExponent(SI.BaseDimensions.LENGTH));
+ assertEquals(1, LENGTH.getExponent(Metric.BaseDimensions.LENGTH));
+ assertEquals(3, VOLUME.getExponent(Metric.BaseDimensions.LENGTH));
}
/**