<commit_before>import endsWith from 'lodash/endsWith'
import filter from 'lodash/filter'
import flatten from 'lodash/flatten'
import includes from 'lodash/includes'
import map from 'lodash/map'
import mapValues from 'lodash/mapValues'
import startsWith from 'lodash/startsWith'
import toPairs from 'lodash/toPairs'
import trim from 'lodash/trim'
import unzip from 'lodash/unzip'

import {
	quacksLikeDeptNum,
	splitDeptNum,
	buildDeptNum,
} from '@gob/school-st-olaf-college'

import {partitionByIndex, splitParagraph, zipToObjectWithArrays} from '@gob/lib'

import departmentMapping from 'sto-course-related-data/handmade/to_department_abbreviations.json'
import gereqMapping from 'sto-course-related-data/handmade/to_gereq_abbreviations.json'

let semesters = {
	fall: 1,
	interim: 2,
	'j-term': 2,
	jterm: 2,
	j: 2,
	spring: 3,
	'summer 1': 4,
	summer1: 4,
	early: 4,
	'early summer': 4,
	'summer session 1': 4,
	'summer session 2': 5,
	late: 5,
	'late summer': 5,
	summer2: 5,
	'summer 2': 5,
	summers: ['$OR', 4, 5],
}

let keywordMappings = {
	day: 'times',
	days: 'times',
	department: 'departments',
	dept: 'departments',
	depts: 'departments',
	ge: 'gereqs',
	gened: 'gereqs',
	geneds: 'gereqs',
	gereq: 'gereqs',
	ges: 'gereqs',
	inst: 'instructors',
	instructor: 'instructors',
	locations: 'location',
	num: 'number',
	place: 'location',
	places: 'location',
	prof: 'instructors',
	profs: 'instructors',
	professor: 'instructors',
	professors: 'instructors',
	sem: 'semester',
	teacher: 'instructors',
	teachers: 'instructors',
	time: 'times',
}

let intKeys = new Set(['year', 'level', 'term', 'number', 'groupid', 'clbid', 'crsid'])
let strKeys = new Set(['title', 'name', 'notes', 'description', 'words'])

function organizeValues([key, values], words = false, profWords = false) {
	let organizedValues = flatMap(values, val => {
		// handle $OR and $AND and other boolean operators
		if (typeof val === 'string' && /^\$/.test(val)) {
			return val.toUpperCase()
		}

		// handle the numeric values
		if (key === 'credits') {
			val = parseFloat(val)
		} else if (intKeys.has(key)) {
			val = parseInt(val, 10)
		}

		// make flow happy by proving that val is now a string
		if (typeof val !== 'string') {
			return val
		}

		// now deal with the strings
		if (key === 'departments') {
			val = val.toLowerCase()
			val = departmentMapping[val] || val.toUpperCase()
		} else if (key === 'gereqs') {
			val = val.toLowerCase()
			val = gereqMapping[val] || val.toUpperCase()
		} else if (key === 'deptnum') {
			val = val.toUpperCase()
		} else if (key === 'semester') {
			val = val.toLowerCase()
			val = semesters[val] || parseInt(val, 10)
		} else if (key === 'instructors' && profWords) {
			val = splitParagraph(val)
			key = 'profWords'
		} else if (key === 'times' || key === 'locations') {
			val = val.toUpperCase()
		} else if (key === 'pf') {
			val = val === 'true'
		} else if (strKeys.has(key)) {
			if (words || key === 'words') {
				val = splitParagraph(val)
				key = 'words'
			} else {
				val = val.trim()
			}
		}

		return val
	})

	return [key, organizedValues]
}

export function buildQueryFromString(queryString = '', opts = {}) {<commit_msg>rework organizeValues around a large switch statement<commit_after>import endsWith from 'lodash/endsWith'
import filter from 'lodash/filter'
import flatten from 'lodash/flatten'
import includes from 'lodash/includes'
import map from 'lodash/map'
import mapValues from 'lodash/mapValues'
import startsWith from 'lodash/startsWith'
import toPairs from 'lodash/toPairs'
import trim from 'lodash/trim'
import unzip from 'lodash/unzip'

import {
	quacksLikeDeptNum,
	splitDeptNum,
	buildDeptNum,
} from '@gob/school-st-olaf-college'

import {partitionByIndex, splitParagraph, zipToObjectWithArrays} from '@gob/lib'

import departmentMapping from 'sto-course-related-data/handmade/to_department_abbreviations.json'
import gereqMapping from 'sto-course-related-data/handmade/to_gereq_abbreviations.json'

let semesters = {
	fall: 1,
	interim: 2,
	'j-term': 2,
	jterm: 2,
	j: 2,
	spring: 3,
	'summer 1': 4,
	summer1: 4,
	early: 4,
	'early summer': 4,
	'summer session 1': 4,
	'summer session 2': 5,
	late: 5,
	'late summer': 5,
	summer2: 5,
	'summer 2': 5,
	summers: ['$OR', 4, 5],
}

let keywordMappings = {
	day: 'times',
	days: 'times',
	department: 'departments',
	dept: 'departments',
	depts: 'departments',
	ge: 'gereqs',
	gened: 'gereqs',
	geneds: 'gereqs',
	gereq: 'gereqs',
	ges: 'gereqs',
	inst: 'instructors',
	instructor: 'instructors',
	locations: 'location',
	num: 'number',
	place: 'location',
	places: 'location',
	prof: 'instructors',
	profs: 'instructors',
	professor: 'instructors',
	professors: 'instructors',
	sem: 'semester',
	teacher: 'instructors',
	teachers: 'instructors',
	time: 'times',
}

function organizeValues([key, values], words = false, profWords = false) {
	let organizedValues = flatMap(values, val => {
		// handle $OR and $AND and other boolean operators
		if (typeof val === 'string' && /^\$/.test(val)) {
			return val.toUpperCase()
		}

		switch (key) {
			// handle the numeric values
			case 'credits':
				return parseFloat(val)
			case 'year':
			case 'level':
			case 'term':
			case 'number':
			case 'groupid':
			case 'clbid':
			case 'crsid':
				return parseInt(val, 10)
			// handle the lookup values
			case 'departments':
				val = val.toLowerCase()
				return departmentMapping[val] || val.toUpperCase()
			case 'gereqs':
				val = val.toLowerCase()
				return gereqMapping[val] || val.toUpperCase()
			case 'semester':
				val = val.toLowerCase()
				return semesters[val] || parseInt(val, 10)
			// handle the string values
			case 'deptnum':
			case 'times':
			case 'locations':
				return val.toUpperCase()
			// handle the boolean values
			case 'pf':
				return val === 'true' ? true : false
			// handle the multi-word values
			case 'instructors':
				if (profWords) {
					key = 'profWords'
					return splitParagraph(val)
				}
				return val.trim()
			case 'title':
			case 'name':
			case 'notes':
			case 'description':
				if (words) {
					key = 'words'
					return splitParagraph(val)
				}
				return val.trim()
			case 'words':
				return splitParagraph(val)
			default:
				return val.trim()
		}
	})

	return [key, organizedValues]
}

export function buildQueryFromString(queryString = '', opts = {}) {
{'fraction_non_alphanumeric': 0.15205414764678105, 'fraction_numerical': 0.008814733196914844, 'mean_word_length': 3.9679437060203284, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, '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': '368169', 'n_tokens_mistral': 2603, 'n_tokens_neox': 2285, 'n_words': 625}