<commit_before>// note.js

var interval = require('./interval');
var assert = require('assert');
var mod = require('mod-loop');
var _ = require('underscore');

var scale = ['C', 'D', 'E', 'F', 'G', 'A', 'B'];

// Map of note to number of half steps from C
var halfStepMap = { 'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11,
  'C#': 1, 'Db': 1, 'D#': 3, 'Eb': 3, 'F#': 6, 'Gb': 6, 'G#': 8, 'Ab': 8, 'A#': 10, 'Bb': 10 };

// Half step offsets for major and perfect intervals
var perfectOffsets = { '-1': 'dim', '0': 'P', '1': 'aug' };
var majorOffsets = { '-2': 'dim', '-1': 'm', 0: 'M', '1': 'aug' };

var accidentals = ['b', 'n', '#'];

var sharpKeys = ['G', 'D', 'A', 'E', 'B', 'F#', 'C#'];
var flatKeys = ['F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb', 'Cb'];

// Parse a note name and return object with letter, accidental
var parseName = function (name) {
  var octave = null;

  // Remove spaces
  name = name.replace(/[\s]/g, '')

  // Resolve 'x' and 's'
  name = name.replace('x', '##').replace('s', '#');

  // Extract octave number if given
  if (/\d$/.test(name)) {
    octave = parseInt(name.slice(-1));
    name = name.slice(0, -1);
  } 

  // Throw an error for an in
  if (!(/^[A-Ga-g](bb|##|[b#n])?$/).test(name)) {
    throw new Error('Invalid note name:  ' + name);
  }

  return {
    letter: name[0].toUpperCase(),
    acc: name.slice(1) || 'n',
    octave: octave
  }
};

// Increase the letter of a note by a given interval
var addNumber = function (note, number) {
  var letter = note.letter;
  var index = scale.indexOf(note.letter);
  var newIndex = mod(index + number - 1, scale.length);

  assert(index > -1);
  assert(newIndex > -1 && newIndex < scale.length);

  return scale[newIndex];
};

// Find the interval number between two notes given their letters
var distanceBet = function (letter1, letter2) {
  var index1 = scale.indexOf(letter1);
  var index2 = scale.indexOf(letter2);
  var distance = mod(index2 - index1 + 1, scale.length);

  assert(index1 > -1);
  assert(index2 > -1);
  assert(distance > 0 && distance <= scale.length)

  return distance;
};

// Find the number of half steps between two notes
var halfStepsBet = function (note1, note2) {
  return mod(halfStepMap[note2] - halfStepMap[note1], 12);
};

// Find the number of half steps to the diatonic interval given inteval number
var getDiatonicHalfSteps = function (number) {
  number = mod(number - 1, scale.length);
  return halfStepMap[scale[number]];
};

// Find the number of half steps between interval and corresponding diatonic interval
var getQualityOffset = function (int) {
  var map = interval.isPerfect(int.number) ? perfectOffsets : majorOffsets;
  var key = _.findKey(map, function (val) {
    return val === int.quality;
  });

  return parseInt(key, 10);
};

// Find the offset between 
var getHalfStepOffset = function (number, halfSteps) {
  var diatonicHalfSteps = diatonicHalfSteps = getDiatonicHalfSteps(number);
  var halfStepOffset = halfSteps - diatonicHalfSteps;

  // Handle various abnormalities
  if (halfStepOffset === 11) halfStepOffset = -1;
  if (halfStepOffset === -11) halfStepOffset = 1;

  return halfStepOffset;
};

var isNote = function (note) {
  return note instanceof Note;
};

var Note = function (name, octave) {
  name = parseName(name);

  this.letter = name.letter;
  this.acc = this.accidental = name.acc;
  this.octave = octave || name.octave;

  // Name does not include 'n' for natural
  this.name = this.letter + (this.acc === 'n' ? '' :  this.acc);

  this.toString = function () {<commit_msg>Used _.invert in note module<commit_after>// note.js

var interval = require('./interval');
var assert = require('assert');
var mod = require('mod-loop');
var _ = require('underscore');

var scale = ['C', 'D', 'E', 'F', 'G', 'A', 'B'];

// Map of note to number of half steps from C
var halfStepMap = { 'C': 0, 'D': 2, 'E': 4, 'F': 5, 'G': 7, 'A': 9, 'B': 11,
  'C#': 1, 'Db': 1, 'D#': 3, 'Eb': 3, 'F#': 6, 'Gb': 6, 'G#': 8, 'Ab': 8, 'A#': 10, 'Bb': 10 };

// Half step offsets for major and perfect intervals
var perfectOffsets = { '-1': 'dim', '0': 'P', '1': 'aug' };
var majorOffsets = { '-2': 'dim', '-1': 'm', 0: 'M', '1': 'aug' };

var accidentals = ['b', 'n', '#'];

var sharpKeys = ['G', 'D', 'A', 'E', 'B', 'F#', 'C#'];
var flatKeys = ['F', 'Bb', 'Eb', 'Ab', 'Db', 'Gb', 'Cb'];

// Parse a note name and return object with letter, accidental
var parseName = function (name) {
  var octave = null;

  // Remove spaces
  name = name.replace(/[\s]/g, '')

  // Resolve 'x' and 's'
  name = name.replace('x', '##').replace('s', '#');

  // Extract octave number if given
  if (/\d$/.test(name)) {
    octave = parseInt(name.slice(-1));
    name = name.slice(0, -1);
  } 

  // Throw an error for an in
  if (!(/^[A-Ga-g](bb|##|[b#n])?$/).test(name)) {
    throw new Error('Invalid note name:  ' + name);
  }

  return {
    letter: name[0].toUpperCase(),
    acc: name.slice(1) || 'n',
    octave: octave
  }
};

// Increase the letter of a note by a given interval
var addNumber = function (note, number) {
  var letter = note.letter;
  var index = scale.indexOf(note.letter);
  var newIndex = mod(index + number - 1, scale.length);

  assert(index > -1);
  assert(newIndex > -1 && newIndex < scale.length);

  return scale[newIndex];
};

// Find the interval number between two notes given their letters
var distanceBet = function (letter1, letter2) {
  var index1 = scale.indexOf(letter1);
  var index2 = scale.indexOf(letter2);
  var distance = mod(index2 - index1 + 1, scale.length);

  assert(index1 > -1);
  assert(index2 > -1);
  assert(distance > 0 && distance <= scale.length)

  return distance;
};

// Find the number of half steps between two notes
var halfStepsBet = function (note1, note2) {
  return mod(halfStepMap[note2] - halfStepMap[note1], 12);
};

// Find the number of half steps to the diatonic interval given inteval number
var getDiatonicHalfSteps = function (number) {
  number = mod(number - 1, scale.length);
  return halfStepMap[scale[number]];
};

// Find the number of half steps between interval and corresponding diatonic interval
var getQualityOffset = function (int) {
  var map = interval.isPerfect(int.number) ? perfectOffsets : majorOffsets;
  var key = _.invert(map)[int.quality];

  return parseInt(key, 10);
};

// Find the offset between 
var getHalfStepOffset = function (number, halfSteps) {
  var diatonicHalfSteps = diatonicHalfSteps = getDiatonicHalfSteps(number);
  var halfStepOffset = halfSteps - diatonicHalfSteps;

  // Handle various abnormalities
  if (halfStepOffset === 11) halfStepOffset = -1;
  if (halfStepOffset === -11) halfStepOffset = 1;

  return halfStepOffset;
};

var isNote = function (note) {
  return note instanceof Note;
};

var Note = function (name, octave) {
  name = parseName(name);

  this.letter = name.letter;
  this.acc = this.accidental = name.acc;
  this.octave = octave || name.octave;

  // Name does not include 'n' for natural
  this.name = this.letter + (this.acc === 'n' ? '' :  this.acc);

  this.toString = function () {
{'fraction_non_alphanumeric': 0.18099419345701742, 'fraction_numerical': 0.018127743945616767, 'mean_word_length': 3.585714285714286, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, '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': '5745595', 'n_tokens_mistral': 2578, 'n_tokens_neox': 2447, 'n_words': 783}