from otree.api import ( models, widgets, BaseConstants, BaseSubsession, BaseGroup, BasePlayer, Currency as c, currency_range ) doc = '' class Constants(BaseConstants): name_in_url = 'task_6P' players_per_group = 6 num_rounds = 150 class Subsession(BaseSubsession): pass class Group(BaseGroup): pass class Player(BasePlayer): group_high = models.BooleanField() count_v = models.IntegerField(blank=True, label='Anzahl des Buchstabens "v"') amount_v = models.IntegerField() previous_count_v = models.IntegerField() previous_amount_v = models.IntegerField() test_skip = models.BooleanField(blank=True, label='Zu Testzwecken: Zur nächsten Stage springen', widget=widgets.RadioSelectHorizontal) img = models.StringField() randomStringimg = models.StringField() stop_button = models.BooleanField(blank=True, initial=False) solved_correctly = models.BooleanField() solved_almost_correctly = models.BooleanField() stop_button_active = models.BooleanField() def generateTask(self): import lipsum import random import string from PIL import Image from PIL import ImageFont from PIL import ImageDraw import boto3 from botocore.client import Config import os #Generate text sentence = lipsum.generate_words(25) #Add a random number (0 - 15) letters (k): k = random.randint(1, 10) length = len(sentence) i = 0 while i <= k: #Add the letter v at a random position: position = random.randint(0, length) sentence = sentence[:position] + 'k' + sentence[position:] i += 1 #Generate image img = Image.new('RGB', (500, 120), color = (240, 240, 240)) #Generate image name letters = string.ascii_lowercase imagename = ''.join(random.choice(letters) for i in range(10)) #Draw text on image #draw_text(sentence, imagename) #Define font font_file_path = 'Roboto-Regular.ttf' font = ImageFont.truetype(font_file_path, size=18, encoding="unic") # create an array with the right amount of lines max_width = 480 text = sentence lines = [] # If the width of the text is smaller than image width # we don't need to split it, just add it to the lines array # and return if font.getsize(text)[0] <= max_width: lines.append(text) else: # split the line by spaces to get words words = text.split(' ') i = 0 # append every word to a line while its width is shorter than image width while i < len(words): line = '' while i < len(words) and font.getsize(line + words[i])[0] <= max_width: line = line + words[i] + " " i += 1 if not line: line = words[i] i += 1 # when the line gets longer than the max width do not append the word, # add the line to the lines array lines.append(line) text_with_breaks = "" for i in lines: text_with_breaks += i+"\n" #print(lines) draw = ImageDraw.Draw(img) color = 'rgb(30, 30, 30)' draw.text((10, 10), text_with_breaks, fill=color, font=font) #img.save('_static\\' + imgname + '.png') img.save('_static/' + imagename + '.png') #Upload file s3 = boto3.resource( # for uploading 's3', aws_access_key_id=os.environ['CLOUDCUBE_ACCESS_KEY_ID'], aws_secret_access_key=os.environ['CLOUDCUBE_SECRET_ACCESS_KEY'], config=Config(signature_version='s3v4') ) imgkey = 'k1ss86en0c36/public/' + self.participant.code + "/" + imagename + '.png' data = open('_static/' + imagename + '.png', 'rb') s3.Bucket('cloud-cube-eu').put_object(Key=imgkey, Body=data) #delete local file os.remove('_static/' + imagename + '.png') print("Anzahl des Buchstaben k:", self.amount_v, " (Spieler ", self.id_in_group,")") if self.amount_v == None: #Save amount_v self.amount_v = sentence.count('k') print("Die Variable amount_v war für Player ", self.id_in_group, "nicht gesetzt.") else: print("ACHTUNG: Die Variable amount_v ist bereits gesetzt für ", self.id_in_group) if self.round_number > 1: self.previous_count_v = self.in_round(self.round_number - 1).count_v self.previous_amount_v = self.in_round(self.round_number - 1).amount_v #Generate randomString letters = string.ascii_lowercase randomString = ''.join(random.choice(letters) for i in range(20)) self.randomStringimg = os.environ['CLOUDCUBE_URL'] + '/public/' + self.participant.code + "/" + imagename + ".png?" + randomString self.img = imagename + ".png" def deleteLastPicture(self): if self.round_number > 1: import os import boto3 from botocore.client import Config s3 = boto3.client( 's3', aws_access_key_id=os.environ['CLOUDCUBE_ACCESS_KEY_ID'], aws_secret_access_key=os.environ['CLOUDCUBE_SECRET_ACCESS_KEY'], config=Config(signature_version='s3v4') ) imgkey = 'k1ss86en0c36/public/' + self.participant.code + '/' + self.in_round(self.round_number - 1).img s3.delete_object(Bucket='cloud-cube-eu', Key=imgkey) def is_number(self): if self.count_v is not None: try: float(self.count_v) return True except ValueError: pass try: import unicodedata unicodedata.numeric(self.count_v) return True except (TypeError, ValueError): pass return False def is_number_p(self): if self.previous_count_v is not None: try: float(self.previous_count_v) return True except ValueError: pass try: import unicodedata unicodedata.numeric(self.previous_count_v) return True except (TypeError, ValueError): pass return False