Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve cli for tips review #813

Merged
merged 19 commits into from
Jul 19, 2022
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,6 @@ outlined on that page and do not file a public issue.
## License
By contributing to Mephisto, you agree that your contributions will be licensed
under the LICENSE file in the root directory of this source tree.

## Dependencies
To add a python dependency you need to add the dependency as well as its version number to the pyproject.toml file.
84 changes: 53 additions & 31 deletions mephisto/scripts/local_db/remove_accepted_tip.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
"""
Script that allows for accepted tips to be removed.
Accepted tips are collected by retrieving all units and then getting the agent of each unit.
The tips for each agent state is filtered to only collect accepted tips.

For each accepted tip you have the option to remove the tip from the agent state.
"""

import enum
from genericpath import exists
from typing import Any, Dict, List
import csv
Expand All @@ -7,6 +16,17 @@
remove_tip_from_metadata,
)
from mephisto.tools.data_browser import DataBrowser as MephistoDataBrowser
from mephisto.tools.scripts import print_out_task_names
from mephisto.utils.rich import console
from rich import print
from rich.prompt import Prompt
from rich.table import Table, Column
from rich import box
Etesam913 marked this conversation as resolved.
Show resolved Hide resolved


class TipsRemovalType(enum.Enum):
REMOVE = "y"
KEEP = "n"


def remove_tip_from_tips_file(
Expand All @@ -27,7 +47,6 @@ def remove_tip_from_tips_file(
with open(tips_location) as read_tips_file:
reader = csv.reader(read_tips_file)
for row in reader:
print(row)
if row[0] != tip_id:
lines_to_write.append(row)

Expand All @@ -40,23 +59,16 @@ def main():
db = LocalMephistoDB()
mephisto_data_browser = MephistoDataBrowser(db)
task_names = mephisto_data_browser.get_task_name_list()
print("\nTask Names:")
for task_name in task_names:
print(task_name)
print("")
task_name = input(
"Enter the name of the task that you want to look at the tips of: \n"
)
print("")
while task_name not in task_names:
print("That task name is not valid\n")
task_name = input(
"Enter the name of the task that you want to look at the tips of: \n"
)
print("")
print_out_task_names(task_names)
task_name = Prompt.ask(
"\nEnter the name of the task that you want to review the tips of",
choices=task_names,
show_choices=False,
).strip()

units = mephisto_data_browser.get_all_units_for_task_name(task_name)
if len(units) == 0:
print("No units were received")
print("[red]No units were received[/red]")
quit()
for unit in units:
if unit.agent_id is not None:
Expand All @@ -65,32 +77,42 @@ def main():
if tips is not None:
accepted_tips = list(filter(lambda tip: tip["accepted"] == True, tips))
accepted_tips_copy = accepted_tips.copy()
acceptable_removal_responses = set(["yes", "y", "no", "n"])

for i in range(len(accepted_tips)):
print("Tip Id: " + accepted_tips[i]["id"])
print("Tip Header: " + accepted_tips[i]["header"])
print("Tip Text: " + accepted_tips[i]["text"])
removal_response = input(
"\nDo you want to remove this tip? yes(y)/no(n): \n"
current_tip_table = Table(
"Property",
Column("Value"),
title="Tip {current_tip} of {total_number_of_tips}".format(
current_tip=i + 1, total_number_of_tips=len(accepted_tips)
),
box=box.ROUNDED,
expand=True,
show_lines=True,
)
current_tip_table.add_row("Tip Id", accepted_tips[i]["id"])
current_tip_table.add_row("Tip Header", accepted_tips[i]["header"])
current_tip_table.add_row("Tip Text", accepted_tips[i]["text"])
console.print(current_tip_table)

removal_response = Prompt.ask(
"\nDo you want to remove this tip? (Default: n)",
choices=[TipsRemovalType.REMOVE, TipsRemovalType.KEEP],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems I was wrong about list, but this can still likely be less verbose with [t.value for t in TipsRemovalType]

default=TipsRemovalType.KEEP,
show_default=False,
).strip()
print("")
while removal_response not in acceptable_removal_responses:
print("That response is not valid\n")
removal_response = input(
"\nDo you want to remove this tip? yes(y)/no(n): \n"
)
print("")
if removal_response == "y" or removal_response == "yes":

if removal_response == TipsRemovalType.REMOVE:
remove_tip_from_tips_file(
accepted_tips_copy, i, unit.get_task_run()
)
remove_tip_from_metadata(
accepted_tips, accepted_tips_copy, i, unit
)
print("Removed tip\n")
elif removal_response == "n" or removal_response == "no":
elif removal_response == TipsRemovalType.KEEP:
print("Did not remove tip\n")
print("There are no more tips to look at!\n")
print("There are no more tips to look at\n")


if __name__ == "__main__":
Expand Down
154 changes: 78 additions & 76 deletions mephisto/scripts/local_db/review_tips_for_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
Rejecting a tip deletes the tip from the tips list in the AgentState's metadata.
It also removed the row in the assets/tips.csv file in your task's directory.
"""

import csv
from genericpath import exists
from pathlib import Path
Expand All @@ -22,6 +21,20 @@
from mephisto.data_model.unit import Unit
from mephisto.data_model.worker import Worker
from mephisto.tools.data_browser import DataBrowser as MephistoDataBrowser
from rich import print
from rich import box
from rich.prompt import Prompt
from rich.prompt import FloatPrompt
from rich.table import Table
from mephisto.tools.scripts import print_out_task_names
from mephisto.utils.rich import console
import enum


class TipsReviewType(enum.Enum):
ACCEPTED = "a"
REJECTED = "r"
SKIP = "s"


def get_index_of_value(lst: List[str], property: str) -> int:
Expand All @@ -31,17 +44,6 @@ def get_index_of_value(lst: List[str], property: str) -> int:
return 0


def is_number(s) -> bool:
"""Validates the input to make sure that it is a number"""
if s == "NaN":
return False
try:
float(s)
return True
except ValueError:
return False


def add_row_to_tips_file(task_run: TaskRun, item_to_add: Dict[str, Any]):
"""Adds a row the tips csv file"""
blueprint_task_run_args = task_run.args["blueprint"]
Expand All @@ -51,7 +53,14 @@ def add_row_to_tips_file(task_run: TaskRun, item_to_add: Dict[str, Any]):
if does_file_exist == False:
# Creates the file
create_tips_file = Path(tips_location)
create_tips_file.touch(exist_ok=True)
try:
create_tips_file.touch(exist_ok=True)
except FileNotFoundError:
print(
"\n[red]Your task folder must have an assets folder in it.[/red]\n"
)
quit()

with open(tips_location, "r") as inp, open(tips_location, "a+") as tips_file:
field_names = list(item_to_add.keys())
writer = csv.DictWriter(tips_file, fieldnames=field_names)
Expand All @@ -75,6 +84,9 @@ def remove_tip_from_metadata(
assigned_agent.state.update_metadata(
property_name="tips", property_value=tips_copy
)
else:
print("[red]An assigned agent was not able to be found for this tip[/red]")
quit()


def accept_tip(tips: List, tips_copy: List, i: int, unit: Unit) -> None:
Expand All @@ -86,42 +98,26 @@ def accept_tip(tips: List, tips_copy: List, i: int, unit: Unit) -> None:

if assigned_agent is not None:
tips_copy[index_to_update]["accepted"] = True
add_row_to_tips_file(unit.get_task_run(), tips_copy[index_to_update])
assigned_agent.state.update_metadata(
property_name="tips", property_value=tips_copy
)
add_row_to_tips_file(unit.get_task_run(), tips_copy[index_to_update])


def main():
db = LocalMephistoDB()
mephisto_data_browser = MephistoDataBrowser(db)
task_names = mephisto_data_browser.get_task_name_list()
acceptable_responses = set(
["a", "accept", "ACCEPT", "Accept", "r", "reject", "REJECT", "Reject"]
)
accept_response = set(["a", "accept", "ACCEPT", "Accept"])
reject_response = set(["r", "reject", "REJECT", "Reject"])
yes_no_responses = set(["yes", "y", "YES", "Yes", "no", "n", "NO", "No"])
yes_response = set(["yes", "y", "YES", "Yes"])
no_response = set(["no", "n", "NO", "No"])

print("\nTask Names:")
for task_name in task_names:
print(task_name)
print_out_task_names(task_names)
task_name = Prompt.ask(
"\nEnter the name of the task that you want to review the tips of",
choices=task_names,
show_choices=False,
).strip()
print("")
task_name = input(
"Enter the name of the task that you want to review the tips of: \n"
)
print("")
while task_name not in task_names:
print("That task name is not valid\n")
task_name = input(
"Enter the name of the task that you want to review the tips of: \n"
)
print("")
units = mephisto_data_browser.get_all_units_for_task_name(task_name)
if len(units) == 0:
print("No units were received")
print("[red]No units were received[/red]")
quit()
for unit in units:
if unit.agent_id is not None:
Expand All @@ -132,63 +128,69 @@ def main():
tips_copy = tips.copy()
for i in range(len(tips)):
if tips[i]["accepted"] == False:
print("Current Tip Id: " + tips[i]["id"] + "\n")
print("Current Tip Header: " + tips[i]["header"] + "\n")
print("Current Tip Text: " + tips[i]["text"] + "\n")
tip_response = input(
"Do you want to accept or reject this tip? accept(a)/reject(r): \n"
current_tip_table = Table(
"Property",
"Value",
title="Tip {current_tip} of {total_number_of_tips}".format(
current_tip=i + 1, total_number_of_tips=len(tips)
),
box=box.ROUNDED,
expand=True,
show_lines=True,
)
current_tip_table.add_row("Tip Id", tips[i]["id"])
current_tip_table.add_row("Tip Header", tips[i]["header"])
current_tip_table.add_row("Tip Text", tips[i]["text"])
console.print(current_tip_table)

tip_response = Prompt.ask(
"\nDo you want to (a)ccept, (r)eject, or (s)kip this tip? (Default: s)",
choices=[
TipsReviewType.ACCEPTED,
TipsReviewType.REJECTED,
TipsReviewType.SKIP,
],
default=TipsReviewType.SKIP,
show_default=False,
).strip()

print("")
while tip_response not in acceptable_responses:
print("That response is not valid\n")
tip_response = input(
"Do you want to accept or reject this tip? accept(a)/reject(r): \n"
)
print("")
if tip_response in accept_response:
if tip_response == TipsReviewType.ACCEPTED:
# persists the tip in the db as it is accepted
accept_tip(tips, tips_copy, i, unit)
print("Tip Accepted\n")
print("[green]Tip Accepted[/green]")
# given the option to pay a bonus to the worker who wrote the tip
is_bonus = input(
"Do you want to pay a bonus to this worker for their tip? yes(y)/no(n): "
bonus = FloatPrompt.ask(
"\nHow much would you like to bonus the tip submitter? (Default: 0.0)",
show_default=False,
default=0.0,
)
while is_bonus not in yes_no_responses:
print("That response is not valid\n")
is_bonus = input(
"Do you want to pay a bonus to this worker for their tip? yes(y)/no(n): \n"
)
print("")
if is_bonus in yes_response:
bonus_amount = input(
"How much money do you want to give: "
if bonus > 0:
reason = Prompt.ask(
"\nWhat reason would you like to give the worker for this tip? NOTE: This will be shared with the worker.(Default: Thank you for submitting a tip!)",
default="Thank you for submitting a tip!",
show_default=False,
)
while is_number(bonus_amount) is False:
print("That is not a number\n")
bonus_amount = input(
"How much money do you want to give: "
)
print("")

reason = input("What is your reason for the bonus: ")
worker_id = float(unit_data["worker_id"])
worker = Worker.get(db, worker_id)
if worker is not None:
bonus_successfully_paid = worker.bonus_worker(
bonus_amount, reason, unit
bonus, reason, unit
)
if bonus_successfully_paid:
print("Bonus Successfully Paid!\n")
print(
"\n[green]Bonus Successfully Paid![/green]\n"
)
else:
print(
"There was an error when paying out your bonus\n"
"\n[red]There was an error when paying out your bonus[/red]\n"
)
elif is_bonus in no_response:
print("No bonus paid\n")

elif tip_response in reject_response:
elif tip_response == TipsReviewType.REJECTED:
remove_tip_from_metadata(tips, tips_copy, i, unit)
print("Tip Rejected\n\n")
print("Tip Rejected\n")
elif tip_response == TipsReviewType.SKIP:
print("Tip Skipped\n")

print("There are no more tips to review\n")

Expand Down
Loading