summaryrefslogtreecommitdiff
path: root/docs
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 /docs
parent236b497f516694929b9fe409508a7cce21ca9e6e (diff)
parent75a5a1a2a40b0eb4361d6fc046eb8918ef6f5292 (diff)
Merge branch 'new-documentation-0.3.1' into develop
Diffstat (limited to 'docs')
-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
8 files changed, 515 insertions, 0 deletions
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}