mechanical-tolerance-calculator 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +1 -1
  2. package/index.js +286 -26
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -29,7 +29,7 @@ console.log(housingTolerances["housingBoresTolerances"]);
29
29
 
30
30
  ---
31
31
 
32
- ## API
32
+ ## API EXACPLES
33
33
 
34
34
  ### `getAllTolerancesFor(materialType: String)`
35
35
 
package/index.js CHANGED
@@ -96,40 +96,299 @@ function returnTolerancesFor(executableMaterialType, spec = "") {
96
96
  };
97
97
  }
98
98
 
99
- function parseNominalFromMeasurement(measurement) {
100
- const nominalString = measurement.toString();
101
- let nominal = "";
102
- for (let index = 0; index < nominalString.length; index++) {
103
- if (nominalString[index] === ".") {
104
- break;
105
- }
106
- nominal += nominalString[index];
99
+ function parseNominalFromMeasurement(measurement, materialType) {
100
+ // For shafts: upper_deviation is 0, so measurement ≤ nominal
101
+ // Therefore, nominal must be ceiling of measurement
102
+ if (materialType === "shafts") {
103
+ return Math.ceil(measurement);
104
+ }
105
+
106
+ // For bores: lower_deviation is 0, so measurement ≥ nominal
107
+ // Therefore, nominal must be floor of measurement
108
+ if (materialType === "housingBores" || materialType === "shellBores") {
109
+ return Math.floor(measurement);
107
110
  }
108
- return parseInt(nominal);
111
+
112
+ // Default: round to nearest
113
+ return Math.round(measurement);
114
+ }
115
+
116
+ const MATERIAL_TYPE_CONFIG = {
117
+ shafts: {
118
+ specification: "h9",
119
+ itGrade: "IT5",
120
+
121
+ rangeMatch: (nominal, spec) =>
122
+ nominal > spec.minimum_diameter && nominal <= spec.maximum_diameter,
123
+ },
124
+ housingBores: {
125
+ specification: "H8",
126
+ itGrade: "IT6",
127
+
128
+ rangeMatch: (nominal, spec) =>
129
+ nominal >= spec.minimum_diameter && nominal < spec.maximum_diameter,
130
+ },
131
+ shellBores: {
132
+ specification: "H9",
133
+ itGrade: "IT6",
134
+ rangeMatch: (nominal, spec) =>
135
+ nominal >= spec.minimum_diameter && nominal < spec.maximum_diameter,
136
+ },
137
+ };
138
+
139
+ function findMatchingSpec(nominal, specs, rangeMatchFn) {
140
+ return specs.find((spec) => rangeMatchFn(nominal, spec)) || null;
141
+ }
142
+
143
+ function calculateComputedBounds(nominal, spec) {
144
+ return {
145
+ upperBound: parseComputedBound(nominal, spec.upper_deviation, 3),
146
+ lowerBound: parseComputedBound(nominal, spec.lower_deviation, 3),
147
+ };
148
+ }
149
+
150
+ function calculateUncomputedBounds(nominal, spec) {
151
+ return {
152
+ upperBound: parseUncomputedBound(nominal, spec.upper_deviation, "+"),
153
+ lowerBound: parseUncomputedBound(nominal, spec.lower_deviation, "-"),
154
+ };
155
+ }
156
+
157
+ function checkMeetsSpecification(measurement, bounds) {
158
+ const measure = parseStringFloat(measurement);
159
+ const upper = parseStringFloat(bounds.upperBound);
160
+ const lower = parseStringFloat(bounds.lowerBound);
161
+
162
+ return measure >= lower && measure <= upper;
163
+ }
164
+
165
+ function processMeasurement(materialType, measurement, tolerances) {
166
+ const config = MATERIAL_TYPE_CONFIG[materialType];
167
+
168
+ if (!config) {
169
+ return {
170
+ error: true,
171
+ message: `Unknown material type: ${materialType}`,
172
+ };
173
+ }
174
+
175
+ // Calculate nominal diameter
176
+ const nominal = parseNominalFromMeasurement(measurement, materialType);
177
+
178
+ // Find matching specification
179
+ const matchedSpec = findMatchingSpec(
180
+ nominal,
181
+ tolerances.specification,
182
+ config.rangeMatch
183
+ );
184
+
185
+ if (!matchedSpec) {
186
+ return {
187
+ error: true,
188
+ message: `No specification found for nominal diameter: ${nominal}`,
189
+ nominal,
190
+ };
191
+ }
192
+
193
+ // Calculate bounds
194
+ const computedBounds = calculateComputedBounds(nominal, matchedSpec);
195
+ const uncomputedBounds = calculateUncomputedBounds(nominal, matchedSpec);
196
+
197
+ // Check if measurement meets specification
198
+ const meetsSpec = checkMeetsSpecification(measurement, computedBounds);
199
+ const specMeetingReason = meetsSpec
200
+ ? `${parseToFixedThreeString(measurement)} falls between ${
201
+ computedBounds.lowerBound
202
+ } and ${computedBounds.upperBound}`
203
+ : `${parseToFixedThreeString(measurement)} doesn't fall between ${
204
+ computedBounds.lowerBound
205
+ } and ${computedBounds.upperBound}`;
206
+
207
+ return {
208
+ measurement: parseStringFloat(measurement),
209
+ nominal,
210
+ specification: config.specification,
211
+ IT_grade: config.itGrade,
212
+ computed_specification_bounds: computedBounds,
213
+ uncomputed_specification_bounds: uncomputedBounds,
214
+ matched_spec: matchedSpec,
215
+
216
+ meets_specification: { meetsSpec, reason: specMeetingReason },
217
+ };
218
+ }
219
+
220
+ function processOneMeasurement(materialType, measurement, tolerances) {
221
+ const processedMeasurement = processMeasurement(
222
+ materialType,
223
+ measurement,
224
+ tolerances
225
+ );
226
+ return {
227
+ ...processedMeasurement,
228
+ meets_IT_tolerance: processedMeasurement.meet_specification,
229
+ };
109
230
  }
110
231
 
111
232
  function checkOneMeasurementFor(materialType, measurement) {
112
233
  const camcoStandardTolerances = getCamcoStandardTolerancesFor(materialType);
113
- let nominal = parseNominalFromMeasurement(measurement);
114
- let matchedSpec = {};
115
- if (camcoStandardTolerances.type === "shafts") {
116
- const shaftNominal = nominal + 1;
117
- const specs = camcoStandardTolerances["specification"];
118
- Array.from(specs).forEach((spec) => {
119
- if (
120
- shaftNominal > spec.minimum_diameter &&
121
- shaftNominal <= spec.maximum_diameter
122
- ) {
123
- matchedSpec = spec;
124
- }
125
- });
126
234
 
127
- const check = Number(matchedSpec.upper_deviation).toFixed(3);
128
- console.log(check);
235
+ if (camcoStandardTolerances.error) {
236
+ return camcoStandardTolerances;
237
+ }
238
+
239
+ if (typeof measurement !== "number" || isNaN(measurement)) {
240
+ return {
241
+ error: true,
242
+ message: "Invalid measurement value",
243
+ };
244
+ }
245
+
246
+ return processOneMeasurement(
247
+ camcoStandardTolerances.type,
248
+ measurement,
249
+ camcoStandardTolerances
250
+ );
251
+ }
252
+
253
+ function parseComputedBound(base, value, decimalCount) {
254
+ return Number(base + parseStringFloat(value)).toFixed(decimalCount);
255
+ }
256
+
257
+ function parseUncomputedBound(value1, value2, sign) {
258
+ if (value2.startsWith("-")) {
259
+ return (
260
+ parseToFixedThreeString(value1) +
261
+ " " +
262
+ sign +
263
+ " " +
264
+ parseToFixedThreeString(value2.slice(1, value2.length))
265
+ );
266
+ }
267
+
268
+ return (
269
+ parseToFixedThreeString(value1) +
270
+ " " +
271
+ sign +
272
+ " " +
273
+ parseToFixedThreeString(value2)
274
+ );
275
+ }
276
+
277
+ function parseToFixedThreeString(value) {
278
+ if (typeof value === "number") {
279
+ return value.toFixed(3);
280
+ }
281
+ return value;
282
+ }
283
+
284
+ /**
285
+ * Converts string float values to actual float numbers
286
+ * @param {string} value - The string representation of a float number
287
+ * @returns {number} - The parsed float number
288
+ */
289
+ function parseStringFloat(value) {
290
+ // Handle edge cases
291
+ if (value === null || value === undefined) {
292
+ return 0;
293
+ }
294
+
295
+ // If it's already a number, return it
296
+ if (typeof value === "number") {
297
+ return value;
298
+ }
299
+
300
+ // Convert string to float
301
+ const parsed = parseFloat(value);
302
+
303
+ // Return 0 if parsing fails (NaN)
304
+ return isNaN(parsed) ? 0 : parsed;
305
+ }
306
+ function processIndividualMeasurement(
307
+ materialType,
308
+ measurement,
309
+ tolerances,
310
+ meetsIT,
311
+ ITMeetingReason
312
+ ) {
313
+ const processedMeasurement = processMeasurement(
314
+ materialType,
315
+ measurement,
316
+ tolerances
317
+ );
318
+ return {
319
+ ...processedMeasurement,
320
+ };
321
+ }
322
+
323
+ function checkMultipleMeasurementsFor(materialType, measurements) {
324
+ const validation = validateMeasurements(measurements);
325
+ if (validation?.error) {
326
+ return validation;
327
+ }
328
+ const camcoStandardTolerances = getCamcoStandardTolerancesFor(materialType);
329
+
330
+ let largestMeasurement = Math.max(...measurements);
331
+ let smallestMeasurement = Math.min(...measurements);
332
+ let ITDifference = parseToFixedThreeString(
333
+ largestMeasurement - smallestMeasurement
334
+ );
335
+
336
+ const ITs = {
337
+ IT5: 0,
338
+ IT6: 0,
339
+ IT7: 0,
340
+ IT8: 0,
341
+ IT9: 0,
342
+ };
343
+
344
+ const results = measurements.map((measurement) => {
345
+ const result = processIndividualMeasurement(
346
+ camcoStandardTolerances.type,
347
+ measurement,
348
+ camcoStandardTolerances
349
+ );
350
+
351
+ ITs[result.IT_grade]++;
352
+
353
+ return result;
354
+ });
355
+
356
+ const baseSpec = results[0];
357
+ const baseITValue = baseSpec.matched_spec[baseSpec.IT_grade];
358
+
359
+ const meetsIT = ITDifference <= baseITValue;
360
+ const itMeetingReason = meetsIT
361
+ ? `The difference between ${parseToFixedThreeString(
362
+ largestMeasurement
363
+ )} and ${parseToFixedThreeString(
364
+ smallestMeasurement
365
+ )} is less than or equal to ${baseITValue}.`
366
+ : `The difference between ${parseToFixedThreeString(
367
+ largestMeasurement
368
+ )} and ${parseToFixedThreeString(
369
+ smallestMeasurement
370
+ )} is greater than to ${baseITValue}.`;
371
+
372
+ return {
373
+ baseSpec,
374
+ meets_IT_Tolerance: { meetsIT, reason: itMeetingReason },
375
+ };
376
+ }
377
+
378
+ function validateMeasurements(measurements) {
379
+ if (!Array.isArray(measurements)) {
380
+ return {
381
+ error: "Measurements must be an array of numbers",
382
+ };
383
+ }
384
+
385
+ if (measurements.length === 0) {
386
+ return {
387
+ error: "Measurements array cannot be empty",
388
+ };
129
389
  }
130
- console.log(nominal);
131
390
 
132
- console.log(matchedSpec);
391
+ return null;
133
392
  }
134
393
 
135
394
  module.exports = {
@@ -137,4 +396,5 @@ module.exports = {
137
396
  getCamcoStandardTolerancesFor,
138
397
  parseNominalFromMeasurement,
139
398
  checkOneMeasurementFor,
399
+ checkMultipleMeasurementsFor,
140
400
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mechanical-tolerance-calculator",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Calculates international standard specification and tolerances for bores, round bars and metals of mechanical units. For examples; H7, H8, H9, h8, h9 specifications and IT5/IT6 tolerances.",
5
5
  "main": "index.js",
6
6
  "scripts": {