import numpy as np
import pandas as pd
characters_all = [
'Man', 'Woman', 'Boy', 'Girl', 'OldMan', 'OldWoman', 'Stroller', 'Pregnant', \
'LargeMan', 'LargeWoman', 'MaleAthlete', 'FemaleAthlete', 'MaleExecutive', 'FemaleExecutive', \
'MaleDoctor', 'FemaleDoctor', 'Homeless', 'Criminal', 'Dog', 'Cat'
]
characters_abstract = [
'Male', 'Female', 'Young', 'Old', 'Infancy', 'Pregnancy',
'Fat', 'Fit', 'Working', 'Medical', 'Homeless', 'Criminal', 'Human',
'Non-human'
]
[docs]def choose_max(x):
"""
Accept a single argmax only; if there is a tie, abstain.
:param x: an nparray of the values; must be in the order `noint`, `int`
"""
if len(np.argwhere(x == np.max(x))) > 1: return -1
return x.argmax()
[docs]def choose_barrier(x, reverse=False):
"""
Choose the scenario where the AV hits the barrier.
If there is no such scenario, abstain.
:param reverse: If false, choose to hit the barrier. Else choose not to.
"""
if x["Passenger_noint"] == 0 and x["Passenger_int"] == 0: return -1
if x["Passenger_noint"] == 1 and x["Passenger_int"] == 1: return -1
elif x["Passenger_noint"] == 1: return 1 if not reverse else 0
elif x["Passenger_int"] == 1: return 0 if not reverse else 1
return -1
[docs]def count_characters(x, suffix, characters):
"""
:param suffix: The suffix to use - int or noint
:param characters: a list of characters to sum up
:return: the number of characters in these groups
"""
return sum([
x["{}_{}".format(c, suffix)] for c in characters
])
[docs]def select_against_homogenous_group(x, group):
"""
Always select against a group if it contains only instances of characters in :group:.
"""
only_group = {
s: x["NumberOfCharacters_{}".format(s)] == count_characters(x, s, group)
for s in ["noint", "int"]
}
if only_group["int"] and only_group["noint"]: return -1
if only_group["noint"]: return 1
if only_group["int"]: return 0
return -1
[docs]def spare_group(x, group):
"""
Never choose an alternative that sacrifices a character in :group:.
"""
group_member_present = {
s: count_characters(x, s, group) > 0
for s in ["noint", "int"]
}
if group_member_present["noint"] and group_member_present["int"]: return -1
if group_member_present["noint"]: return 0
if group_member_present["int"]: return 1
return -1
[docs]def is_passenger(df, suf=''):
return df['Barrier{}'.format(suf)] == 1
[docs]def is_law_abiding(df, suf=''):
return df['CrossingSignal{}'.format(suf)] == 1 & ~is_passenger(df, suf=suf)
[docs]def is_law_violating(df, suf=''):
return df['CrossingSignal{}'.format(suf)] == 2 & ~is_passenger(df, suf=suf)
[docs]def pictofy(response, raw=False):
if raw:
crossing_light = ["๐ด" if is_law_violating(response, suf=suf).iloc[0] else "๐ข" if is_law_abiding(response, suf=suf).iloc[0] else " " for suf in ["_noint", "_int"]]
pedped = ["๐ง" if is_passenger(response, suf=suf).iloc[0] else "๐ธ" for s in ["noint", "int"]]
else:
crossing_light = ["๐ด" if response["Law Violating_{}".format(suf)].iloc[0] else "๐ข" if response["Law Abiding_{}".format(suf)].iloc[0] else " " for suf in ["noint", "int"]]
pedped = ["๐ง" if response["Passenger_{}".format(s)].iloc[0] else "๐ธ" for s in ["noint", "int"]]
out_string = \
"What should the self-driving car do? (ScenarioType: {})\n\n".format(response["ScenarioType"].iloc[0] if "ScenarioType" in response.columns else "Unknown") +\
"\t ๐ \n" +\
"\t |\t\\ \n" +\
"\t v \t v\n" +\
"\t{}{} \t{}{}\n".format(crossing_light[0], *pedped, crossing_light[1]) +\
"\t NOINT\tINT\t\n"
for k, s in {"INT": "int", "NOINT": "noint"}.items():
out_dict = {col: response["{}_{}".format(col, s)] for col in (characters_all if raw else characters_abstract)}
out_list = []
for c, v in out_dict.items():
if not raw:
if (int(v)) > 0:
out_list.append("{} {}".format(int(v), c.split("_")[0]))
else:
for i in range(int(v)):
out_list.append(c.split("_")[0])
out_string += "{} saves: \n{}\n".format(k, out_list)
print(out_string)