Using the Density of Water to Calibrate Volumetric Glassware

Stephen Lukacs (2) iquanta.org/instruct/python

Enter the temperature of the purified water: °C, Enter the mass to calibrate: g 

The following equation is a fit to only the "Valves 5" data for it is the most complete and consistent compared to the other references:
dH2O(T(°C)) = -1.374183E-10*T^4 + 4.373884E-08*T^3 + -7.782389E-06*T^2 + 5.961310E-05*T + 0.999881 g/mL ... R2 = 0.99999811
{"data":[{"mode":"markers","name":"U.S.A. 1","x":[0,4.0,4.4,10,15.6,21,26.7,32.2,37.8,48.9,60,71.1,82.2,93.3,100],"y":[0.99987,1.0,0.99999,0.99975,0.99907,0.99802,0.99669,0.9951,0.99318,0.9887,0.98338,0.97729,0.97056,0.96333,0.95865],"type":"scatter"},{"marker":{"symbol":"x"},"mode":"markers","name":"OpenStax 2","x":[0,4,10,15,20,22,25,30,40,60,80,100],"y":[0.9998395,0.999972,0.9997026,0.9991026,0.9982071,0.9977735,0.9970479,0.9956502,0.9922,0.9832,0.9718,0.9584],"type":"scatter"},{"marker":{"symbol":"diamond"},"mode":"markers","name":"Harris 3","x":[10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30],"y":[0.9997026,0.9996084,0.9995004,0.9993801,0.9992474,0.9991026,0.998946,0.9987779,0.9985986,0.9984082,0.9982071,0.9979955,0.9977735,0.9975415,0.9972995,0.9970479,0.9967867,0.9965162,0.9962365,0.9959478,0.9956502],"type":"scatter"},{"marker":{"symbol":"cross"},"mode":"markers","name":"Harris 4","x":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,37],"y":[0.999842,0.999901,0.999942,0.999966,0.999974,0.999966,0.999942,0.999904,0.999805,0.999783,0.999702,0.999607,0.9995,0.999379,0.999247,0.999102,0.998945,0.998777,0.998598,0.998408,0.998207,0.997995,0.997773,0.997541,0.997299,0.997047,0.996786,0.996515,0.996235,0.995947,0.995649,0.993329],"type":"scatter"},{"line":{"width":2},"mode":"lines","name":"fit","x":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100],"y":[0.9998814715038258,0.9999333458143601,0.9999699158563926,0.9999914391159049,0.9999981697808403,0.9999903587411033,0.9999682535885598,0.9999320986170372,0.9998821348223244,0.9998185999021716,0.9997417282562905,0.9996517509863543,0.9995488958959976,0.9994333874908162,0.9993054469783678,0.9991652922681709,0.9990131379717061,0.9988491954024149,0.9986736725757006,0.9984867742089277,0.9982887017214223,0.9980796532344717,0.9978598235713247,0.9976294042571919,0.9973885835192449,0.9971375462866167,0.996876474190402,0.9966055455636569,0.9963249354413988,0.9960348155606065,0.9957353543602204,0.9954267169811424,0.9951090652662353,0.9947825577603241,0.9944473497101946,0.9941035930645943,0.9937514364742321,0.9933910252917785,0.9930225015718651,0.992646004071085,0.9922616682479931,0.9918696262631053,0.991470006978899,0.9910629359598132,0.9906485354722483,0.9902269244845661,0.9897982186670896,0.9893625303921038,0.9889199687338543,0.988470639468549,0.9880146450743567,0.9875520847314077,0.9870830543217939,0.9866076464295684,0.986125950340746,0.9856380520433027,0.985144034227176,0.9846439762842649,0.9841379543084298,0.9836260410954925,0.9831083061432361,0.9825848156514054,0.9820556325217066,0.9815208163578071,0.9809804234653358,0.9804345068518833,0.9798831162270012,0.9793262980022029,0.9787640952909631,0.9781965479087178,0.9776236923728647,0.9770455619027627,0.9764621864197323,0.9758735925470551,0.9752798036099746,0.9746808396356954,0.9740767173533837,0.9734674501941671,0.9728530482911345,0.9722335184793364,0.9716088642957845,0.9709790859794523,0.9703441804712744,0.969704141414147,0.9690589591529276,0.9684086207344353,0.9677531099074506,0.9670924071227153,0.9664264895329326,0.9657553309927673,0.9650789020588457,0.9643971699897553,0.9637100987460452,0.9630176489902256,0.9623197780867687,0.9616164401021077,0.9609075858046372,0.9601931626647137,0.9594731148546546,0.958747383248739,0.9580159054232074],"type":"scatter"},{"marker":{"size":3.5,"symbol":"square"},"mode":"markers","name":"Valves 5","x":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100],"y":[0.99982,0.99989,0.99994,0.99998,1.0,1.0,0.99999,0.99996,0.99991,0.99985,0.99977,0.99968,0.99958,0.99946,0.99933,0.99919,0.99903,0.99886,0.99868,0.99849,0.99829,0.99808,0.99786,0.99762,0.99738,0.99713,0.99686,0.99659,0.99631,0.99602,0.99571,0.99541,0.99509,0.99476,0.99443,0.99408,0.99373,0.99337,0.993,0.99263,0.99225,0.99186,0.99146,0.99105,0.99064,0.99022,0.9898,0.98936,0.98892,0.98847,0.98802,0.98756,0.98709,0.98662,0.98614,0.98565,0.98516,0.98466,0.98416,0.98364,0.98313,0.9826,0.98207,0.98154,0.981,0.98045,0.9799,0.97934,0.97878,0.97821,0.97763,0.97705,0.97647,0.97588,0.97528,0.97468,0.97408,0.97346,0.97285,0.97223,0.9716,0.97097,0.97033,0.96969,0.96904,0.96839,0.96773,0.96707,0.96641,0.96574,0.96506,0.96438,0.9637,0.96301,0.96231,0.96162,0.96091,0.9602,0.95949,0.95878,0.95805],"type":"scatter"}],"layout":{"template":{"data":{"histogram2dcontour":[{"type":"histogram2dcontour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"choropleth":[{"type":"choropleth","colorbar":{"outlinewidth":0,"ticks":""}}],"histogram2d":[{"type":"histogram2d","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"heatmap":[{"type":"heatmap","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"contourcarpet":[{"type":"contourcarpet","colorbar":{"outlinewidth":0,"ticks":""}}],"contour":[{"type":"contour","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"surface":[{"type":"surface","colorbar":{"outlinewidth":0,"ticks":""},"colorscale":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]]}],"mesh3d":[{"type":"mesh3d","colorbar":{"outlinewidth":0,"ticks":""}}],"scatter":[{"fillpattern":{"fillmode":"overlay","size":10,"solidity":0.2},"type":"scatter"}],"parcoords":[{"type":"parcoords","line":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolargl":[{"type":"scatterpolargl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"bar":[{"error_x":{"color":"#2a3f5f"},"error_y":{"color":"#2a3f5f"},"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"bar"}],"scattergeo":[{"type":"scattergeo","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterpolar":[{"type":"scatterpolar","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"histogram":[{"marker":{"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"histogram"}],"scattergl":[{"type":"scattergl","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatter3d":[{"type":"scatter3d","line":{"colorbar":{"outlinewidth":0,"ticks":""}},"marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermap":[{"type":"scattermap","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattermapbox":[{"type":"scattermapbox","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scatterternary":[{"type":"scatterternary","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"scattercarpet":[{"type":"scattercarpet","marker":{"colorbar":{"outlinewidth":0,"ticks":""}}}],"carpet":[{"aaxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"baxis":{"endlinecolor":"#2a3f5f","gridcolor":"white","linecolor":"white","minorgridcolor":"white","startlinecolor":"#2a3f5f"},"type":"carpet"}],"table":[{"cells":{"fill":{"color":"#EBF0F8"},"line":{"color":"white"}},"header":{"fill":{"color":"#C8D4E3"},"line":{"color":"white"}},"type":"table"}],"barpolar":[{"marker":{"line":{"color":"#E5ECF6","width":0.5},"pattern":{"fillmode":"overlay","size":10,"solidity":0.2}},"type":"barpolar"}],"pie":[{"automargin":true,"type":"pie"}]},"layout":{"autotypenumbers":"strict","colorway":["#636efa","#EF553B","#00cc96","#ab63fa","#FFA15A","#19d3f3","#FF6692","#B6E880","#FF97FF","#FECB52"],"font":{"color":"#2a3f5f"},"hovermode":"closest","hoverlabel":{"align":"left"},"paper_bgcolor":"white","plot_bgcolor":"#E5ECF6","polar":{"bgcolor":"#E5ECF6","angularaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"radialaxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"ternary":{"bgcolor":"#E5ECF6","aaxis":{"gridcolor":"white","linecolor":"white","ticks":""},"baxis":{"gridcolor":"white","linecolor":"white","ticks":""},"caxis":{"gridcolor":"white","linecolor":"white","ticks":""}},"coloraxis":{"colorbar":{"outlinewidth":0,"ticks":""}},"colorscale":{"sequential":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"sequentialminus":[[0.0,"#0d0887"],[0.1111111111111111,"#46039f"],[0.2222222222222222,"#7201a8"],[0.3333333333333333,"#9c179e"],[0.4444444444444444,"#bd3786"],[0.5555555555555556,"#d8576b"],[0.6666666666666666,"#ed7953"],[0.7777777777777778,"#fb9f3a"],[0.8888888888888888,"#fdca26"],[1.0,"#f0f921"]],"diverging":[[0,"#8e0152"],[0.1,"#c51b7d"],[0.2,"#de77ae"],[0.3,"#f1b6da"],[0.4,"#fde0ef"],[0.5,"#f7f7f7"],[0.6,"#e6f5d0"],[0.7,"#b8e186"],[0.8,"#7fbc41"],[0.9,"#4d9221"],[1,"#276419"]]},"xaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"yaxis":{"gridcolor":"white","linecolor":"white","ticks":"","title":{"standoff":15},"zerolinecolor":"white","automargin":true,"zerolinewidth":2},"scene":{"xaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"yaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2},"zaxis":{"backgroundcolor":"#E5ECF6","gridcolor":"white","linecolor":"white","showbackground":true,"ticks":"","zerolinecolor":"white","gridwidth":2}},"shapedefaults":{"line":{"color":"#2a3f5f"}},"annotationdefaults":{"arrowcolor":"#2a3f5f","arrowhead":0,"arrowwidth":1},"geo":{"bgcolor":"white","landcolor":"#E5ECF6","subunitcolor":"white","showland":true,"showlakes":true,"lakecolor":"white"},"title":{"x":0.05},"mapbox":{"style":"light"}}},"xaxis":{"title":{"text":"Temperature (\u00b0C)"}},"yaxis":{"title":{"text":"Density (g\u002fmL)"}},"title":{"text":"Density of Water at various Temperatures"},"height":750}}

The data, its temperature in °C, and its corresponding density of water:
  1. U.S. Department of the Interior, Bureau of Reclaimation, 1977, Ground Water Manual, from The Water Encyclopedia, Third Edition, Hydrologic Data and Internet Resources, Edited by Pedro Fierro, Jr. and Evan K. Nyler, (2007), website → ((0, 0.99987), (4.0, 1.0), (4.4, 0.99999), (10, 0.99975), (15.6, 0.99907), (21, 0.99802), (26.7, 0.99669), (32.2, 0.9951), (37.8, 0.99318), (48.9, 0.9887), (60, 0.98338), (71.1, 0.97729), (82.2, 0.97056), (93.3, 0.96333), (100, 0.95865)).
  2. OpenStax Chemistry: Atoms First 2ed. → ((0, 0.9998395), (4, 0.999972), (10, 0.9997026), (15, 0.9991026), (20, 0.9982071), (22, 0.9977735), (25, 0.9970479), (30, 0.9956502), (40, 0.9922), (60, 0.9832), (80, 0.9718), (100, 0.9584)).
  3. Harris, Daniel C. and Lucy, Charles A., Quantitative Chemical Analysis, 9th ed., (2016), W.H. Freeman and Company, New York, NY. → ((10, 0.9997026), (11, 0.9996084), (12, 0.9995004), (13, 0.9993801), (14, 0.9992474), (15, 0.9991026), (16, 0.998946), (17, 0.9987779), (18, 0.9985986), (19, 0.9984082), (20, 0.9982071), (21, 0.9979955), (22, 0.9977735), (23, 0.9975415), (24, 0.9972995), (25, 0.9970479), (26, 0.9967867), (27, 0.9965162), (28, 0.9962365), (29, 0.9959478), (30, 0.9956502)).
  4. Harris, Daniel C. and Lucy, Charles A., Quantitative Chemical Analysis, 10th ed., (2020), W.H. Freeman and Company, New York, NY. → ((0, 0.999842), (1, 0.999901), (2, 0.999942), (3, 0.999966), (4, 0.999974), (5, 0.999966), (6, 0.999942), (7, 0.999904), (8, 0.999805), (9, 0.999783), (10, 0.999702), (11, 0.999607), (12, 0.9995), (13, 0.999379), (14, 0.999247), (15, 0.999102), (16, 0.998945), (17, 0.998777), (18, 0.998598), (19, 0.998408), (20, 0.998207), (21, 0.997995), (22, 0.997773), (23, 0.997541), (24, 0.997299), (25, 0.997047), (26, 0.996786), (27, 0.996515), (28, 0.996235), (29, 0.995947), (30, 0.995649), (37, 0.993329)).
  5. Valves Instruments Plus Ltd, Astley, Manchester, website → ((0, 0.99982), (1, 0.99989), (2, 0.99994), (3, 0.99998), (4, 1.0), (5, 1.0), (6, 0.99999), (7, 0.99996), (8, 0.99991), (9, 0.99985), (10, 0.99977), (11, 0.99968), (12, 0.99958), (13, 0.99946), (14, 0.99933), (15, 0.99919), (16, 0.99903), (17, 0.99886), (18, 0.99868), (19, 0.99849), (20, 0.99829), (21, 0.99808), (22, 0.99786), (23, 0.99762), (24, 0.99738), (25, 0.99713), (26, 0.99686), (27, 0.99659), (28, 0.99631), (29, 0.99602), (30, 0.99571), (31, 0.99541), (32, 0.99509), (33, 0.99476), (34, 0.99443), (35, 0.99408), (36, 0.99373), (37, 0.99337), (38, 0.993), (39, 0.99263), (40, 0.99225), (41, 0.99186), (42, 0.99146), (43, 0.99105), (44, 0.99064), (45, 0.99022), (46, 0.9898), (47, 0.98936), (48, 0.98892), (49, 0.98847), (50, 0.98802), (51, 0.98756), (52, 0.98709), (53, 0.98662), (54, 0.98614), (55, 0.98565), (56, 0.98516), (57, 0.98466), (58, 0.98416), (59, 0.98364), (60, 0.98313), (61, 0.9826), (62, 0.98207), (63, 0.98154), (64, 0.981), (65, 0.98045), (66, 0.9799), (67, 0.97934), (68, 0.97878), (69, 0.97821), (70, 0.97763), (71, 0.97705), (72, 0.97647), (73, 0.97588), (74, 0.97528), (75, 0.97468), (76, 0.97408), (77, 0.97346), (78, 0.97285), (79, 0.97223), (80, 0.9716), (81, 0.97097), (82, 0.97033), (83, 0.96969), (84, 0.96904), (85, 0.96839), (86, 0.96773), (87, 0.96707), (88, 0.96641), (89, 0.96574), (90, 0.96506), (91, 0.96438), (92, 0.9637), (93, 0.96301), (94, 0.96231), (95, 0.96162), (96, 0.96091), (97, 0.9602), (98, 0.95949), (99, 0.95878), (100, 0.95805)).
"""
reference: https://iquanta.org/instruct/python ::: Chemistry 1, The Density of Water ::: Stephen Lukacs, Ph.D. ©2023-10-22
"""
from py4web import URL, request
from yatl.helpers import *
from iquanta.mcp import is_str_float, str_to_float
from numpy import mean, polyfit
import plotly.graph_objects as go

BR, B = TAG['br/'], TAG['b']
<page_scripts>
<style>
</style>
</page_scripts>

def doFit(x, y, deg):
    fit, ymean = polyfit(x, y, deg, full=True), mean(y)
    #RSquared verified with Mathematica LinearModelFit["RSquared"]
    SSres, SStot = fit[1][0], sum([(d - ymean)**2 for d in y])
    return fit[0], (1 - SSres / SStot)

data1 = ((0, 0.99987,), (4.0, 1.00000,), (4.4, 0.99999,), (10, 0.99975,), (15.6, 0.99907,), (21, 0.99802,), (26.7, 0.99669,), (32.2, 0.99510,), (37.8, 0.99318,), (48.9, 0.98870,), (60, 0.98338,), (71.1, 0.97729,), (82.2, 0.97056,), (93.3, 0.96333,), (100, 0.95865,),)
data2 = ((0, 0.9998395,), (4, 0.9999720,), (10, 0.9997026,), (15, 0.9991026,), (20, 0.9982071,), (22, 0.9977735,), (25, 0.9970479,), (30, 0.9956502,), (40, 0.9922,), (60, 0.9832,), (80, 0.9718,), (100, 0.9584,),)
data3 = ((10, 0.9997026,), (11, 0.9996084,), (12, 0.9995004,), (13, 0.9993801,), (14, 0.9992474,), (15, 0.9991026,), (16, 0.9989460,), (17, 0.9987779,), (18, 0.9985986,), (19,  0.9984082,), (20, 0.9982071,), (21, 0.9979955,), (22, 0.9977735,), (23, 0.9975415,), (24, 0.9972995,), (25, 0.9970479,), (26, 0.9967867,), (27, 0.9965162,), (28, 0.9962365,), (29, 0.9959478,), (30, 0.9956502,),)
data4 = ((0, 0.999842), (1, 0.999901), (2, 0.999942), (3, 0.999966), (4, 0.999974), (5, 0.999966), (6, 0.999942), (7, 0.999904), (8, 0.999805), (9, 0.999783), (10, 0.999702), (11, 0.999607), (12, 0.999500), (13, 0.999379), (14, 0.999247), (15, 0.999102), (16, 0.998945), (17, 0.998777), (18, 0.998598), (19, 0.998408), (20, 0.998207), (21, 0.997995), (22, 0.997773), (23, 0.997541), (24, 0.997299), (25, 0.997047), (26, 0.996786), (27, 0.996515), (28, 0.996235), (29, 0.995947), (30, 0.995649), (37, 0.993329),)
data5 = ((0, 0.99982), (1, 0.99989), (2, 0.99994), (3, 0.99998), (4, 1.0), (5, 1.0), (6, 0.99999), (7, 0.99996), (8, 0.99991), (9, 0.99985), (10, 0.99977), (11, 0.99968), (12, 0.99958), (13, 0.99946), (14, 0.99933), (15, 0.99919), (16, 0.99903), (17, 0.99886), (18, 0.99868), (19, 0.99849), (20, 0.99829), (21, 0.99808), (22, 0.99786), (23, 0.99762), (24, 0.99738), (25, 0.99713), (26, 0.99686), (27, 0.99659), (28, 0.99631), (29, 0.99602), (30, 0.99571), (31, 0.99541), (32, 0.99509), (33, 0.99476), (34, 0.99443), (35, 0.99408), (36, 0.99373), (37, 0.99337), (38, 0.993), (39, 0.99263), (40, 0.99225), (41, 0.99186), (42, 0.99146), (43, 0.99105), (44, 0.99064), (45, 0.99022), (46, 0.9898), (47, 0.98936), (48, 0.98892), (49, 0.98847), (50, 0.98802), (51, 0.98756), (52, 0.98709), (53, 0.98662), (54, 0.98614), (55, 0.98565), (56, 0.98516), (57, 0.98466), (58, 0.98416), (59, 0.98364), (60, 0.98313), (61, 0.9826), (62, 0.98207), (63, 0.98154), (64, 0.981), (65, 0.98045), (66, 0.9799), (67, 0.97934), (68, 0.97878), (69, 0.97821), (70, 0.97763), (71, 0.97705), (72, 0.97647), (73, 0.97588), (74, 0.97528), (75, 0.97468), (76, 0.97408), (77, 0.97346), (78, 0.97285), (79, 0.97223), (80, 0.9716), (81, 0.97097), (82, 0.97033), (83, 0.96969), (84, 0.96904), (85, 0.96839), (86, 0.96773), (87, 0.96707), (88, 0.96641), (89, 0.96574), (90, 0.96506), (91, 0.96438), (92, 0.9637), (93, 0.96301), (94, 0.96231), (95, 0.96162), (96, 0.96091), (97, 0.9602), (98, 0.95949), (99, 0.95878), (100, 0.95805),)
#data = data1 + data2 + data3 + data4 + data5#adding lists makes one flattened list of (x,y) pairs
data = data5

x, y = [d[0] for d in data], [d[1] for d in data]
fit2nd, RSquared2nd = doFit(x, y, 2)
eq2nd = '{0:6E}*T^2 + {1:6E}*T + {2:6f}'.format(*fit2nd)
fit3rd, RSquared3rd = doFit(x, y, 3)
eq3rd = '{0:6E}*T^3 + {1:6E}*T^2 + {2:6E}*T + {3:6f}'.format(*fit3rd)
fit4th, RSquared4th = doFit(x, y, 4)
eq4th = '{0:6E}*T^4 + {1:6E}*T^3 + {2:6E}*T^2 + {3:6E}*T + {4:6f}'.format(*fit4th)

rtn = FORM(_method="post")
if ('temperature' in request.forms) and isinstance(request.forms['temperature'], str) and (request.forms['temperature'].strip() != ''):
    try:
        temperature = float(request.forms['temperature'])
    except:
        temperature = 22.5
    s2, s3, s4 = eq2nd.replace('T', f'{temperature}').replace('^', '**'), eq3rd.replace('T', f'{temperature}').replace('^', '**'), eq4th.replace('T', f'{temperature}').replace('^', '**')
    density = round(eval(s4), 7)
    cat = CAT('the density of water is ', B(density, ' g/mL '), ' at ', B(XML(f'{temperature}&deg;C')))
    if ('mass' in request.forms) and isinstance(request.forms['mass'], str) and (request.forms['mass'].strip() != ''):
        try:
            mass = float(request.forms['mass'])
            cat.append(CAT(', the calibrated volume of water is ', B(round(mass / density, 3), ' mL '), ' at ', B(XML(f'{temperature}&deg;C'))))
        except:
        	pass
    rtn.append(P(cat, B("."), _style="margin: 0px; padding: 6px 0px; font-size: 16pt;",))

rtn.append(STYLE("input[type=text] { height: 30px; width: 120px; padding: 0px 2px; text-align: center; }"))
rtn.append(CAT(BR(), "Enter the temperature of the purified water: ", INPUT(_type="text", _name="temperature", _value=f"{temperature if ('temperature' in locals()) else 22.5}"), XML('&deg;C, Enter the mass to calibrate: '), INPUT(_type="text", _name="mass", _value=f"{mass if ('mass' in locals()) else 100.0}"), XML("g&emsp;"), INPUT(_type="submit", _value="Compute", _style="border: 2px solid gray;")))
rtn.append(CAT(*[BR()]*2, "The following equation is a fit to only the \"Valves 5\" data for it is the most complete and consistent compared to the other references:", BR(), XML("<b>d<sub>H2O</sub>(T(°C)) = "), eq4th, XML(" g/mL</b>&emsp;...&emsp;R<sup>2</sup> = "), f'{RSquared4th:.8f}'))

fig = go.Figure()
xss = sorted(set([d[0] for d in data])) #x sorted set unique x
#using eval on the string eq3rd...
#s3 = eval(eq3rd.replace('^', '**'))
#or, using a lambda function...
#s3x = lambda T: fit3rd[0]*T**3 + fit3rd[1]*T**2 + fit3rd[2]*T + fit3rd[3]
s4x = lambda T: fit4th[0]*T**4 + fit4th[1]*T**3 + fit4th[2]*T**2 + fit4th[3]*T + fit4th[4]
#
fig.add_trace(go.Scatter(x=[d[0] for d in data1], y=[d[1] for d in data1], mode="markers", name="U.S.A. 1"))
fig.add_trace(go.Scatter(x=[d[0] for d in data2], y=[d[1] for d in data2], mode="markers", name="OpenStax 2", marker=go.scatter.Marker(symbol='x')))
fig.add_trace(go.Scatter(x=[d[0] for d in data3], y=[d[1] for d in data3], mode="markers", name="Harris 3", marker=go.scatter.Marker(symbol='diamond')))
fig.add_trace(go.Scatter(x=[d[0] for d in data4], y=[d[1] for d in data4], mode="markers", name="Harris 4", marker=go.scatter.Marker(symbol='cross')))
fig.add_trace(go.Scatter(x=xss, y=[s4x(d) for d in xss], mode="lines", name="fit", line=go.scatter.Line(width=2)))
fig.add_trace(go.Scatter(x=[d[0] for d in data5], y=[d[1] for d in data5], mode="markers", name="Valves 5", marker=go.scatter.Marker(size=3.5, symbol='square')))
fig.update_layout(xaxis=go.XAxis(title="Temperature (°C)"), yaxis=go.YAxis(title="Density (g/mL)"))
fig.update_layout(title_text="Density of Water at various Temperatures", height=750)
rtn.append(CAT(DIV(XML(fig.to_json()), _id="figure0"),))

t1 = A('website', _href="https://www.usgs.gov/special-topics/water-science-school/science/water-density", _target="waterdensity")
t2 = A('website', _href="https://www.vip-ltd.co.uk/Expansion/Density_Of_Water_Tables.pdf", _target="waterdensity")
rtn.append(CAT(BR(), "The data, its temperature in °C, and its corresponding density of water:", OL(LI(XML(f"U.S. Department of the Interior, Bureau of Reclaimation, 1977, Ground Water Manual, from The Water Encyclopedia, Third Edition, Hydrologic Data and Internet Resources, Edited by Pedro Fierro, Jr. and Evan K. Nyler, (2007), {t1} &rarr; {data1}.")), LI(XML(f"OpenStax Chemistry: Atoms First 2ed. &rarr; {data2}.")), LI(XML(f"Harris, Daniel C. and Lucy, Charles A., Quantitative Chemical Analysis, 9th ed., (2016), W.H. Freeman and Company, New York, NY. &rarr; {data3}.")), LI(XML(f"Harris, Daniel C. and Lucy, Charles A., Quantitative Chemical Analysis, 10th ed., (2020), W.H. Freeman and Company, New York, NY. &rarr; {data4}.")), LI(XML(f"Valves Instruments Plus Ltd, Astley, Manchester, {t2} &rarr; {data5}.")))))