Last active
November 10, 2019 03:10
-
-
Save deargle/f454a156d3a72adf62869e2ef09101d8 to your computer and use it in GitHub Desktop.
batch create hits using psiturk
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
set -e | |
#set -x | |
set -o nounset # aka set -u | |
# WHAT IS THIS | |
# ------------- | |
# This will use the `psiturk -e` functionality to post batches of hits to mturk, with each hit | |
# having no more than 9 assignments so that requesters don't get hammered by the extra 20% commission (yeesh). | |
# | |
# | |
# USAGE | |
# --------- | |
# The script has to be run from the same directory where your project's config.txt is located. | |
# | |
# First, set the varibles at the beginning of the script (see the SET THESE section) | |
# | |
# Then, run the script on its own to make sure things look right: | |
# ./psiturk_batcher.sh | |
# | |
# and then say 'no' so that you can launch it in the background instead. | |
# | |
# When things look right, launch it with `nohup`, redirect everything to a log file of your choice, | |
# and give it a 'y' so that the confirmation prompt is accepted, like this: | |
# | |
# (echo y | nohup ./psiturk_batcher.sh | ts) > mylog.log 2>&1 & | |
# | |
# the `ts` will prepend a timestamp to each entry in the logfile. It's part of the `moreutils` package. | |
# | |
# Note: I only tested this on Debian so things may explode in non-GNU environments. | |
# Hopefully you can figure out how to tweak it. | |
# | |
# Don't forget to change your config.txt to `launch_in_sandbox_mode = false` so that this script creates live hits for you. | |
# | |
# Okay go get'em! | |
############################## | |
# SET THESE | |
############################## | |
TOTAL_ASSIGNMENTS=200 | |
SPACING=5 # the time to sleep before posting a new batch. put it in seconds | |
HIT_REWARD='1.00' | |
HIT_DURATION='1' | |
MAX_ASSIGNMENTS_PER_HIT=9 | |
# DONE_BY | |
# something that `date -d` can understand, then convert it to seconds. | |
# See <https://www.gnu.org/software/coreutils/manual/html_node/Relative-items-in-date-strings.html#Relative-items-in-date-strings> for formats | |
DONE_BY=$(date -d 1minute +%s) | |
############################## | |
TOTAL_TIME=$(( ${DONE_BY}-$(date +%s) )) | |
NUM_ROUNDS=$(( $TOTAL_TIME / $SPACING )) | |
ASSIGNMENTS_PER_ROUND=$(( $TOTAL_ASSIGNMENTS / $NUM_ROUNDS )) | |
TOTAL_ASSIGNMENTS_DONE_WITHOUT_MODULUS=$(( NUM_ROUNDS * ASSIGNMENTS_PER_ROUND )) | |
ASSIGNMENTS_REMAINDER_TO_DISTRIBUTE=$(( TOTAL_ASSIGNMENTS % TOTAL_ASSIGNMENTS_DONE_WITHOUT_MODULUS )) | |
PSITURK_EXECUTE_FORMAT="hit create %s $HIT_REWARD $HIT_DURATION" | |
# <http://stackoverflow.com/questions/3231804/in-bash-how-to-add-are-you-sure-y-n-to-any-command-or-alias> | |
function confirm { | |
# call with a prompt string or use a default | |
read -e -r -p "${1:-Are you sure? [y/N]} " response | |
case $response in | |
[yY][eE][sS]|[yY]) | |
true | |
;; | |
*) | |
false | |
;; | |
esac | |
} | |
meta=$(printf "%s\n" \ | |
"Total time: $TOTAL_TIME seconds" \ | |
"Spacing: ${SPACING} seconds" \ | |
"Total assignments: ${TOTAL_ASSIGNMENTS}" \ | |
"Assignments per round (ignoring modulus): ${ASSIGNMENTS_PER_ROUND}") | |
echo "$meta" # so it goes to the logs... | |
echo | |
confirm_message=$(printf "%s\n" "$meta" '' 'Continue? [y/N] ') | |
confirm "${confirm_message}" || { echo 'exited...'; exit 0; } | |
echo | |
for (( i=1; i<=NUM_ROUNDS; i++ )); do | |
echo "# ROUND ${i} FIGHT" | |
num_assignments_this_round=$ASSIGNMENTS_PER_ROUND | |
if (( i <= ASSIGNMENTS_REMAINDER_TO_DISTRIBUTE )); then | |
((num_assignments_this_round++)) | |
fi | |
num_hits_this_round=$(( num_assignments_this_round / MAX_ASSIGNMENTS_PER_HIT )) | |
num_assignments_for_modulus_hit=$(( num_assignments_this_round % MAX_ASSIGNMENTS_PER_HIT)) | |
echo "TOTAL assignments for this round: $num_assignments_this_round" | |
for (( j=1; j<=num_hits_this_round; j++ )); do | |
echo "Creating a hit with ${MAX_ASSIGNMENTS_PER_HIT} assignments." | |
psiturk_execute=$(printf "$PSITURK_EXECUTE_FORMAT" $MAX_ASSIGNMENTS_PER_HIT) | |
psiturk -e "$psiturk_execute" | |
done | |
# do one more hit creation, with the modulus. | |
if (( num_assignments_for_modulus_hit > 0 )); then | |
echo "Creating a hit with ${num_assignments_for_modulus_hit} assignments." | |
psiturk_execute=$(printf "$PSITURK_EXECUTE_FORMAT" $num_assignments_for_modulus_hit) | |
psiturk -e "$psiturk_execute" | |
fi | |
echo | |
echo "Sleeping for ${SPACING} seconds..."; sleep ${SPACING} | |
echo | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment