import re # comparison regex _FULL_ = r"\d+\s*[<>=]+\s*\w+\s*[<>=]+\s*\d+" # Helper functions def search_songs(searchterm, cache): def match_song(song, term): term = term.lower() values = [song['title_orig'], song['title_en']] values.extend([i for tpl in [(a['name_orig'], a['name_en']) for a in song['artists']] for i in tpl]) if song['source']: values.extend([song['source']['name_orig'], song['source']['name_en']]) for field in values: if term in field.lower(): return True return False return [song for song in cache if match_song(song, searchterm)] def parse_difficulty(term): if isinstance(term, str): term.lower() if term in [0, 'e', 'k', 'easy', 'kantan']: return 'd_kantan' elif term in [1, 'n', 'f', 'normal', 'futsuu']: return 'd_futsuu' elif term in [2, 'h', 'm', 'hard', 'muzukashii', 'muzu']: return 'd_muzukashii' elif term in [3, 'o', 'extreme', 'oni']: return 'd_oni' elif term in [4, 'u', 'extra', 'ura']: return 'd_ura' else: return None def parse_comparison(data): digits = [int(d) for d in re.findall(r"\d+", data) ] operators = re.findall(r"[<>=]+", data) assert(len(digits) == len(operators)) # Handle shortened expressions if not re.match(_FULL_, data): if operators[0] == digits[0]: # digit = operator or vice versa return digits[0] if data.index(str(digits[0])) < data.index(operators[0]): # digit < x digits.append(10) operators.append("<=") else: # x < digit digits.insert(0, 1) operators.insert(0, "<=") # Someone tried to do something funky like d > x < d OR d < x > d if (any( x in ("<", "<=") for x in operators) and any( x in (">", ">=") for x in operators)): if operators[0] in (">", ">="): # range from 0 to lowest low = min(digits) op = operators[digits.index(low)] if op in ("<=", ">="): # Soft boundaries: +1 (will be cut at range) low += 1 return list(range(1,low)) else: # range from 10 to highest high = max(digits) op = operators[digits.index(high)] if op in ("<", ">"): # Hard boundaries: +1 high += 1 return list(range(high, 11)) # Adjust if operators[0] == "<": digits[0] += 1 elif operators[0] == ">": digits[0] -= 1 elif operators[0] == "=": return [digits[0]] if operators[1] == "<": digits[1] -= 1 elif operators[1] == ">": digits[1] += 1 elif operators[1] == "=": return [digits[1]] if digits[0] > digits[1]: digits = list(reversed(digits)) return list(range(digits[0], digits[1]+1))