Spaces:
Running
Running
from __future__ import absolute_import | |
from __future__ import division | |
from __future__ import print_function | |
"""Utilities specific to this project.""" | |
from collections import namedtuple | |
from six import string_types | |
##################### | |
# BF-lang utilities # | |
##################### | |
BF_EOS_INT = 0 # Also used as SOS (start of sequence). | |
BF_EOS_CHAR = TEXT_EOS_CHAR = '_' | |
BF_LANG_INTS = range(1, 9) | |
BF_INT_TO_CHAR = [BF_EOS_CHAR, '>', '<', '+', '-', '[', ']', '.', ','] | |
BF_CHAR_TO_INT = dict([(c, i) for i, c in enumerate(BF_INT_TO_CHAR)]) | |
RewardInfo = namedtuple('RewardInfo', ['episode_rewards', 'input_case', | |
'correct_output', | |
'code_output', 'reason', 'input_type', | |
'output_type']) | |
class IOType(object): | |
string = 'string' | |
integer = 'integer' | |
boolean = 'boolean' | |
class IOTuple(tuple): | |
pass | |
def flatten(lst): | |
return [item for row in lst for item in row] | |
def bf_num_tokens(): | |
# BF tokens plus EOS. | |
return len(BF_INT_TO_CHAR) | |
def bf_char2int(bf_char): | |
"""Convert BF code char to int token.""" | |
return BF_CHAR_TO_INT[bf_char] | |
def bf_int2char(bf_int): | |
"""Convert BF int token to code char.""" | |
return BF_INT_TO_CHAR[bf_int] | |
def bf_tokens_to_string(bf_tokens, truncate=True): | |
"""Convert token list to code string. Will truncate at EOS token. | |
Args: | |
bf_tokens: Python list of ints representing the code string. | |
truncate: If true, the output string will end at the first EOS token. | |
If false, the entire token list is converted to string. | |
Returns: | |
String representation of the tokens. | |
Raises: | |
ValueError: If bf_tokens is not a python list. | |
""" | |
if not isinstance(bf_tokens, list): | |
raise ValueError('Only python list supported here.') | |
if truncate: | |
try: | |
eos_index = bf_tokens.index(BF_EOS_INT) | |
except ValueError: | |
eos_index = len(bf_tokens) | |
else: | |
eos_index = len(bf_tokens) | |
return ''.join([BF_INT_TO_CHAR[t] for t in bf_tokens[:eos_index]]) | |
def bf_string_to_tokens(bf_string): | |
"""Convert string to token list. Will strip and append EOS token.""" | |
tokens = [BF_CHAR_TO_INT[char] for char in bf_string.strip()] | |
tokens.append(BF_EOS_INT) | |
return tokens | |
def tokens_to_text(tokens): | |
"""Convert token list to human readable text.""" | |
return ''.join( | |
[TEXT_EOS_CHAR if t == 0 else chr(t - 1 + ord('A')) for t in tokens]) | |
################################### | |
# Number representation utilities # | |
################################### | |
# https://en.wikipedia.org/wiki/Metric_prefix | |
si_magnitudes = { | |
'k': 1e3, | |
'm': 1e6, | |
'g': 1e9} | |
def si_to_int(s): | |
"""Convert string ending with SI magnitude to int. | |
Examples: 5K ==> 5000, 12M ==> 12000000. | |
Args: | |
s: String in the form 'xx..xP' where x is a digit and P is an SI prefix. | |
Returns: | |
Integer equivalent to the string. | |
""" | |
if isinstance(s, string_types) and s[-1].lower() in si_magnitudes.keys(): | |
return int(int(s[:-1]) * si_magnitudes[s[-1].lower()]) | |
return int(s) | |
def int_to_si(n): | |
"""Convert integer to string with SI magnitude. | |
`n` will be truncated. | |
Examples: 5432 ==> 5k, 12345678 ==> 12M | |
Args: | |
n: Integer to represent as a string. | |
Returns: | |
String representation of `n` containing SI magnitude. | |
""" | |
m = abs(n) | |
sign = -1 if n < 0 else 1 | |
if m < 1e3: | |
return str(n) | |
if m < 1e6: | |
return '{0}K'.format(sign*int(m / 1e3)) | |
if m < 1e9: | |
return '{0}M'.format(sign*int(m / 1e6)) | |
if m < 1e12: | |
return '{0}G'.format(sign*int(m / 1e9)) | |
return str(m) | |