Skip to content

Commit

Permalink
add massPercentage() (#7)
Browse files Browse the repository at this point in the history
* add massPercentage
  • Loading branch information
RobTillaart authored Jan 1, 2023
1 parent 4efeb34 commit 3cd13aa
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 78 deletions.
105 changes: 54 additions & 51 deletions AtomicWeight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// FILE: AtomicWeight.cpp
// AUTHOR: Rob Tillaart
// DATE: 2022-03-09
// VERSION: 0.1.1
// VERSION: 0.1.3
// PURPOSE: Arduino library for atomic weights
// URL: https://github.com/RobTillaart/AtomicWeight

Expand Down Expand Up @@ -144,7 +144,7 @@ elements[119] =
};


PTOE::PTOE(uint8_t size)
PTOE::PTOE(const uint8_t size)
{
_size = size;
}
Expand All @@ -156,60 +156,92 @@ uint8_t PTOE::size()
}


uint8_t PTOE::electrons(uint8_t el)
uint8_t PTOE::electrons(const uint8_t el)
{
return el;
}


uint8_t PTOE::neutrons(uint8_t el)
uint8_t PTOE::neutrons(const uint8_t el)
{
return round(weight(el) - el);
}


uint8_t PTOE::protons(uint8_t el)
uint8_t PTOE::protons(const uint8_t el)
{
return el;
}


float PTOE::weight(uint8_t el)
float PTOE::weight(const uint8_t el)
{
return elements[el].weight * _weightFactor;
}


float PTOE::weight(const char * formula)
float PTOE::weight(const char * formula, const char * el)
{
return weight((char*) formula);
p = (char *)formula;
return _weight('\0', el);
}


float PTOE::weight(char * formula)
float PTOE::massPercentage(const char * formula, const char * el)
{
p = formula;
return _weight('\0');
float total = weight(formula);
if (total == 0) return 0;
p = (char *)formula;
return 100.0 * _weight('\0', el) / total;
}


float PTOE::_weight(char sep)
char * PTOE::name(const uint8_t el)
{
return elements[el].name;
}


uint8_t PTOE::find(const char * abbrev)
{
// how about caching here?
for (uint8_t i = 0; i < _size; i++)
{
if (strcmp(elements[i].name, abbrev) == 0) return i;
}
return 255;
}


////////////////////////////////////////////////////////////////
//
// DEBUG
//
float PTOE::weightFactor()
{
return _weightFactor;
}


////////////////////////////////////////////////////////////////
//
// PRIVATE
//
float PTOE::_weight(const char sep, const char * el)
{
float sum = 0;
float w = 0;
char elem[3] = { 0, 0, 0 };
int count = 0;

// char *p = formula;
while (*p != sep)
{
w = 0;
// HANDLE GROUP (...)
if (*p == '(')
{
p++; // skip '('
w = _weight(')');
// Serial.println(w);
w = _weight(')', el);
p++; // skip ')'
}
else
Expand All @@ -224,9 +256,13 @@ float PTOE::_weight(char sep)
elem[1] = *p;
p++;
}
int z = find(elem);
if (z == 255) return 0; // fail
w = weight(z);
// can be optimized
if ((el == NULL) || (strcmp(elem, el) == 0))
{
int z = find(elem);
if (z == 255) return 0; // fail
w = weight(z);
}
}

count = 0;
Expand All @@ -249,38 +285,5 @@ float PTOE::_weight(char sep)
}


char * PTOE::name(uint8_t el)
{
return elements[el].name;
}


uint8_t PTOE::find(const char * abbrev)
{
return find((char *) abbrev);
}


uint8_t PTOE::find(char * abbrev)
{
for (uint8_t i = 0; i < _size; i++)
{
if (strcmp(elements[i].name, abbrev) == 0) return i;
}
return 255;
}


////////////////////////////////////////////////////////////////
//
// DEBUG
//
float PTOE::weightFactor()
{
return _weightFactor;
}



// -- END OF FILE --

31 changes: 17 additions & 14 deletions AtomicWeight.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
// FILE: AtomicWeight.h
// AUTHOR: Rob Tillaart
// DATE: 2022-03-09
// VERSION: 0.1.2
// VERSION: 0.1.3
// PURPOSE: Arduino library for atomic weights
// URL: https://github.com/RobTillaart/AtomicWeight


#include "Arduino.h"

#define ATOMIC_WEIGHT_LIB_VERSION (F("0.1.2"))
#define ATOMIC_WEIGHT_LIB_VERSION (F("0.1.3"))


/////////////////////////////////////////////////////////////////////////
Expand All @@ -20,23 +20,26 @@
class PTOE
{
public:
PTOE(uint8_t size = 118); // all by default
PTOE(const uint8_t size = 118); // all by default
uint8_t size();


uint8_t electrons(uint8_t el);
uint8_t neutrons(uint8_t el);
uint8_t protons(uint8_t el);
uint8_t electrons(const uint8_t el);
uint8_t neutrons(const uint8_t el);
uint8_t protons(const uint8_t el);

// weight of one atom
float weight(const uint8_t el);

float weight(uint8_t el);
float weight(const char * formula);
float weight(char * formula);
// if (el != NULL) weights one element in a formula, e.g el == "H"
// if (el == NULL) weights the whole formula
float weight(const char * formula, const char * el = NULL);

// mass percentage of one element in a formula.
float massPercentage(const char * formula, const char * el);


char * name(uint8_t el);
char * name(const uint8_t el);
uint8_t find(const char * abbrev);
uint8_t find(char * abbrev);


// DEBUG
Expand All @@ -47,11 +50,11 @@ class PTOE
uint8_t _size;
const float _weightFactor = 1.0 / 222.909;

float _weight(char sep);
// if (el == NULL) ==> whole weight otherwise only of element.
float _weight(char sep, const char * el);
char *p; // for _weight().
};



// -- END OF FILE --

10 changes: 9 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,21 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## [0.1.3] - 2023-01-01
- refactor interface
- add **weight(formula, element)**
- add **massPercentage(formula, element)**
- fix version number in .cpp
- update readme.md.
- update keywords.txt


## [0.1.2] - 2023-01-01
- add weight(formula) group () support
- rewrote example
- update readme.md.
- add unit tests


## [0.1.1] - 2022-12-30
- fix offset in some functions
- move code to .cpp file
Expand Down
29 changes: 20 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,27 @@ The parameter **element** in the following functions is 0..118.
- **uint8_t protons(uint8_t element)** returns the number of protons of the element.
- **float weight(uint8_t element)** returns the weight of the element.
The error < 0.3%, table uses "weight compression".
- **float weight(char \* formula)** returns the weight of a molecule e.g. "H2O".
Returns 0 if it cannot parse the formula given.
Cannot parse complex formulas with brackets () in it.
- **float weight(char \* formula, char \* abbreviation == NULL)** see below.
- If (el != NULL) returns the total weight of one element in a formula
- if (el == NULL) returns the weight of the whole formula
- Returns 0 if it cannot parse the formula given.
- **float massPercentage(char \* formula, char \* abbreviation)**
Returns mass percentage of a selected element in a formula

- **uint8_t find(char \* abbreviation)** returns the element number.
- **char \* name(uint8_t element)** returns the abbreviation of element.


#### weight

The **weight(int n)** function returns the weight of a single atom.
The **weight(formula)** function is meant to calculate the weight of a molecule.
The **weight(int n)** call returns the weight of a single atom (by index).
The **weight(formula)** call is meant to calculate the weight of a molecule.
A molecule defined as one or more atoms.

The latter function does not care about the order of the atoms.
So "C6H6" is equal to "H6C6" or even "CCCCCCHHHHHH" or "C3H3C3H3" etc.
Elements are defined as 1 or two characters long.
The first must be uppercase, the second must be lowercase.
Elements are defined as one or two characters long.
The first must be upper case, the (optional) second must be lower case.
If no number is provided the count of 1 is assumed.

The functions returns a float, so to get the integer weight, one should use **round()**.
Expand All @@ -80,6 +85,11 @@ Valid formula's might look as:
- "C6(COOH)2" compound molecule, with repeating groups
- "YBa2Cu3O7" some superconductor-ish material

(Since 0.1.3)
The **weight(formula, element)** function is meant to calculate the total weight of one element
in a molecule. E.g one can weigh the H atoms in H2O (2 of 18).



#### debug

Expand Down Expand Up @@ -109,12 +119,13 @@ See examples
- liquid, gas, solid, unknown (2 bits per element) = ~30 bytes
- (short) table of English names
- which ones ?
- function **float massPercentage("H2O", "H")** ~10%
- function **float atomicPercentage("H2O", "H")** ~33%
- performance functions
- especially **find()** ?
- case (in)sensitive **find()**
- is there a faster data structure.
- is there a faster data structure?
- search by nr is O(1)
- search by name is O(n)

#### wont (unless)

Expand Down
Loading

0 comments on commit 3cd13aa

Please sign in to comment.