<commit_before>import interact from 'interact.js';

/**
 * Determine the floating point precision of a number.
 * @param value
 * @returns {number}
 */
export function getFloatPrecision(value) {
  return value > 0 && value < 1 ? (1 - Math.ceil(Math.log(value) / Math.log(10))) : 0;
}

/**
 * Return a number to a specified precision as a workaround for floating point funkiness.
 * @param value
 * @param precision
 * @returns {number}
 */
export function valueWithPrecision(value, precision) {
  return +value.toFixed(precision);
}

export function getSnapTargetFunc(snapTarget, snapGridArgs = {}) {
  if (typeof snapTarget === 'function') {
    return snapTarget;
  } else if (typeof snapTarget === 'object') {
    return interact.createSnapGrid({
      ...snapGridArgs,
      ...snapTarget,
    });
  }
  return null;
}

export function getDimension(value) {
  if (typeof value === 'string') {
    return value;
  }
  return `${value}px`;
}<commit_msg>extract `stateFromPropUpdates` function and make supporting `updateFunc` function<commit_after>import interact from 'interact.js';
import reduce from 'lodash/reduce';

/**
 * Determine the floating point precision of a number.
 * @param value
 * @returns {number}
 */
export function getFloatPrecision(value) {
  return value > 0 && value < 1 ? (1 - Math.ceil(Math.log(value) / Math.log(10))) : 0;
}

/**
 * Return a number to a specified precision as a workaround for floating point funkiness.
 * @param value
 * @param precision
 * @returns {number}
 */
export function valueWithPrecision(value, precision) {
  return +value.toFixed(precision);
}

export function getSnapTargetFunc(snapTarget, snapGridArgs = {}) {
  if (typeof snapTarget === 'function') {
    return snapTarget;
  } else if (typeof snapTarget === 'object') {
    return interact.createSnapGrid({
      ...snapGridArgs,
      ...snapTarget,
    });
  }
  return null;
}

export function getDimension(value) {
  if (typeof value === 'string') {
    return value;
  }
  return `${value}px`;
}

export function stateFromPropUpdates(propUpdates, prevProps, nextProps, state) {
  return reduce(propUpdates, (acc, value, key) => {
    return value(acc, key, prevProps, nextProps);
  }, state);
}

export function updateFunc(func) {
  return (acc, key, prevProps = {}, nextProps) => {
    return prevProps[key] !== nextProps[key] ?
      { ...acc, ...func(nextProps[key], key, nextProps) } :
      acc;
  };
}
{'fraction_non_alphanumeric': 0.1393239901071723, 'fraction_numerical': 0.00494641384995878, 'mean_word_length': 3.8250497017892644, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3594801', 'n_tokens_mistral': 753, 'n_tokens_neox': 738, 'n_words': 216}