From 3c72b05feb6eb005b7e24f93c772e5aef3db748c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Mon, 26 Feb 2024 13:06:10 +0100 Subject: [PATCH] fix!: improve types in zones functions --- src/zones/__tests__/zonesWithPoints.test.ts | 128 ++++++++++---------- src/zones/zonesNormalize.ts | 32 ++--- src/zones/zonesWithPoints.ts | 66 +++++----- 3 files changed, 119 insertions(+), 107 deletions(-) diff --git a/src/zones/__tests__/zonesWithPoints.test.ts b/src/zones/__tests__/zonesWithPoints.test.ts index 3e2bc873..a927b281 100644 --- a/src/zones/__tests__/zonesWithPoints.test.ts +++ b/src/zones/__tests__/zonesWithPoints.test.ts @@ -2,75 +2,73 @@ import { FromTo } from 'cheminfo-types'; import { zonesWithPoints } from '../zonesWithPoints'; -describe('zonesWithPoints', () => { - it('no zones', () => { - const zones: FromTo[] = []; - const result = zonesWithPoints(zones, 1024); - expect(result).toStrictEqual([]); - }); +test('no zones', () => { + const zones: FromTo[] = []; + const result = zonesWithPoints(zones, 1024); + expect(result).toStrictEqual([]); +}); - it('one zone', () => { - const zones = [{ from: 0, to: 10 }]; - const result = zonesWithPoints(zones, 1024); - expect(result).toStrictEqual([{ from: 0, to: 10, numberOfPoints: 1024 }]); - }); +test('one zone', () => { + const zones = [{ from: 0, to: 10 }]; + const result = zonesWithPoints(zones, 1024); + expect(result).toStrictEqual([{ from: 0, to: 10, numberOfPoints: 1024 }]); +}); - it('two zones', () => { - const zones = [ - { from: 0, to: 1 }, - { from: 4, to: 5 }, - ]; - const result = zonesWithPoints(zones, 1024); - expect(result).toStrictEqual([ - { from: 0, to: 1, numberOfPoints: 512 }, - { from: 4, to: 5, numberOfPoints: 512 }, - ]); - }); +test('two zones', () => { + const zones = [ + { from: 0, to: 1 }, + { from: 4, to: 5 }, + ]; + const result = zonesWithPoints(zones, 1024); + expect(result).toStrictEqual([ + { from: 0, to: 1, numberOfPoints: 512 }, + { from: 4, to: 5, numberOfPoints: 512 }, + ]); +}); - it('two asymmetric zones', () => { - const zones = [ - { from: 0, to: 1 }, - { from: 4, to: 7 }, - ]; - const result = zonesWithPoints(zones, 1024); - expect(result).toStrictEqual([ - { from: 0, to: 1, numberOfPoints: 256 }, - { from: 4, to: 7, numberOfPoints: 768 }, - ]); - }); +test('two asymmetric zones', () => { + const zones = [ + { from: 0, to: 1 }, + { from: 4, to: 7 }, + ]; + const result = zonesWithPoints(zones, 1024); + expect(result).toStrictEqual([ + { from: 0, to: 1, numberOfPoints: 256 }, + { from: 4, to: 7, numberOfPoints: 768 }, + ]); +}); - it('two asymmetric zones with from, to', () => { - const zones = [ - { from: 0, to: 1 }, - { from: 4, to: 7 }, - ]; - const result = zonesWithPoints(zones, 1024, { from: 2, to: 10 }); - expect(result).toStrictEqual([{ from: 4, to: 7, numberOfPoints: 1024 }]); - }); +test('two asymmetric zones with from, to', () => { + const zones = [ + { from: 0, to: 1 }, + { from: 4, to: 7 }, + ]; + const result = zonesWithPoints(zones, 1024, { from: 2, to: 10 }); + expect(result).toStrictEqual([{ from: 4, to: 7, numberOfPoints: 1024 }]); +}); - it('tree asymmetric zones with overlap', () => { - const zones = [ - { from: 0, to: 1 }, - { from: 0, to: 3 }, - { from: 4, to: 7 }, - ]; - const result = zonesWithPoints(zones, 1024); - expect(result).toStrictEqual([ - { from: 0, to: 3, numberOfPoints: 512 }, - { from: 4, to: 7, numberOfPoints: 512 }, - ]); - }); +test('tree asymmetric zones with overlap', () => { + const zones = [ + { from: 0, to: 1 }, + { from: 0, to: 3 }, + { from: 4, to: 7 }, + ]; + const result = zonesWithPoints(zones, 1024); + expect(result).toStrictEqual([ + { from: 0, to: 3, numberOfPoints: 512 }, + { from: 4, to: 7, numberOfPoints: 512 }, + ]); +}); - it('tree asymmetric zones with touch', () => { - const zones = [ - { from: 0, to: 1 }, - { from: 1, to: 3 }, - { from: 4, to: 7 }, - ]; - const result = zonesWithPoints(zones, 1024); - expect(result).toStrictEqual([ - { from: 0, to: 3, numberOfPoints: 512 }, - { from: 4, to: 7, numberOfPoints: 512 }, - ]); - }); +test('tree asymmetric zones with touch', () => { + const zones = [ + { from: 0, to: 1 }, + { from: 1, to: 3 }, + { from: 4, to: 7 }, + ]; + const result = zonesWithPoints(zones, 1024); + expect(result).toStrictEqual([ + { from: 0, to: 3, numberOfPoints: 512 }, + { from: 4, to: 7, numberOfPoints: 512 }, + ]); }); diff --git a/src/zones/zonesNormalize.ts b/src/zones/zonesNormalize.ts index 60bc104c..58382506 100644 --- a/src/zones/zonesNormalize.ts +++ b/src/zones/zonesNormalize.ts @@ -1,5 +1,22 @@ +/* eslint-disable max-lines-per-function */ + import { FromTo } from 'cheminfo-types'; +export interface ZonesNormalizeOptions { + /** specify min value of zones + * @default Number.NEGATIVE_INFINITY + */ + from?: number; + /** specify max value of zones + * @default Number.POSITIVE_INFINITY + */ + to?: number; + /** + * List of exclusion zones + */ + exclusions?: FromTo[]; +} + /** * Normalize an array of zones: * - ensure than from < to @@ -12,20 +29,7 @@ import { FromTo } from 'cheminfo-types'; */ export function zonesNormalize( zones: FromTo[] = [], - options: { - /** specify min value of zones - * @default Number.NEGATIVE_INFINITY - */ - from?: number; - /** specify max value of zones - * @default Number.POSITIVE_INFINITY - */ - to?: number; - /** - * List of exclusion zones - */ - exclusions?: FromTo[]; - } = {}, + options: ZonesNormalizeOptions = {}, ): FromTo[] { const { exclusions = [] } = options; let { from = Number.NEGATIVE_INFINITY, to = Number.POSITIVE_INFINITY } = diff --git a/src/zones/zonesWithPoints.ts b/src/zones/zonesWithPoints.ts index b1260691..8a75fe1e 100644 --- a/src/zones/zonesWithPoints.ts +++ b/src/zones/zonesWithPoints.ts @@ -1,5 +1,22 @@ +import { FromTo } from 'cheminfo-types'; + import { zonesNormalize } from './zonesNormalize'; +export interface ZonesWithPointsOptions { + /** specify min value of zones + * @default Number.NEGATIVE_INFINITY + */ + from?: number; + /** specify max value of zones + * @default Number.POSITIVE_INFINITY + */ + to?: number; +} + +export interface FromToWithNumberOfPoints extends FromTo { + numberOfPoints: number; +} + /** * Add the number of points per zone to reach a specified total * @@ -9,49 +26,42 @@ import { zonesNormalize } from './zonesNormalize'; * @returns array of zones with points */ export function zonesWithPoints( - zones: Array<{ - /** start of zone*/ - from: number; - /** end of zone */ - to: number; - }> = [], + zones: FromTo[] = [], /** * total number of points to distribute between zones * @default 10 */ numberOfPoints = 10, - options: { - /** specify min value of zones - * @default Number.NEGATIVE_INFINITY - */ - from?: number; - /** specify max value of zones - * @default Number.POSITIVE_INFINITY - */ - to?: number; - } = {}, -): Array<{ from: number; to: number; numberOfPoints?: number }> { - if (zones.length === 0) return zones; - const returnZones = zonesNormalize(zones, options); - - const totalSize = returnZones.reduce((previous, current) => { + options: ZonesWithPointsOptions = {}, +): FromToWithNumberOfPoints[] { + if (zones.length === 0) return []; + const normalizedZones = zonesNormalize(zones, options); + const zonesWithNumberOfPoints: FromToWithNumberOfPoints[] = []; + + const totalSize = normalizedZones.reduce((previous, current) => { return previous + (current.to - current.from); }, 0); const unitsPerPoint = totalSize / numberOfPoints; let currentTotal = 0; - for (let i = 0; i < returnZones.length - 1; i++) { - const tempZone: any = returnZones[i]; - tempZone.numberOfPoints = Math.min( + for (let i = 0; i < normalizedZones.length - 1; i++) { + const tempZone = normalizedZones[i]; + const tempZoneNumberOfPoints = Math.min( Math.round((tempZone.to - tempZone.from) / unitsPerPoint), numberOfPoints - currentTotal, ); - currentTotal += tempZone.numberOfPoints; + zonesWithNumberOfPoints.push({ + ...tempZone, + numberOfPoints: tempZoneNumberOfPoints, + }); + currentTotal += tempZoneNumberOfPoints; } - const zone: any = returnZones[returnZones.length - 1]; - zone.numberOfPoints = numberOfPoints - currentTotal; + zonesWithNumberOfPoints.push({ + ...normalizedZones[normalizedZones.length - 1], + numberOfPoints: numberOfPoints - currentTotal, + }); - return returnZones; + return zonesWithNumberOfPoints; }