#1 by ckormylo
Hi all -
I have a 20 round game where each round I must assign a "price movement" and a "suggested investment amount". There are 500 different variations of these 20 rounds so I have them in a CSV file with columns "ID", "Round", "PriceMovement", "SuggInvest". On the results screen I have a chart that plots the price movement dynamically. So in Round 1, it has 1 data point and in Round 5 it has 5 data points.
I am currently setting 20 different player variables, r1 = models.FloatField(), r2 = models.FloatField... etc.
Then I have a function that triggers as below:
def set_values(player):
subsession = player.subsession
round = player.round_number
for i in range(1, round + 1):
exec(f"player.r{i} = price_dict[i]")
Finally, the html generates the graph via:
<script>
google.charts.load('current', {packages: ['corechart', 'line']});
google.charts.setOnLoadCallback(drawBasic);
function drawBasic() {
var data = new google.visualization.DataTable();
data.addColumn('number', 'Round');
data.addColumn('number', 'Price');
var roundNumber = {{ subsession.round_number }};
data.addRows([
[0, 100],
[1, {{ player.r1 }}],
[2, {{ player.r2 }}],
[3, {{ player.r3 }}],
[4, {{ player.r4 }}],
[5, {{ player.r5 }}],
[6, {{ player.r6 }}],
[7, {{ player.r7 }}],
[8, {{ player.r8 }}],
[9, {{ player.r9 }}],
[10, {{ player.r10 }}],
[11, {{ player.r11 }}],
[12, {{ player.r12 }}],
[13, {{ player.r13 }}],
[14, {{ player.r14 }}],
[15, {{ player.r15 }}],
[16, {{ player.r16 }}],
[17, {{ player.r17 }}],
[18, {{ player.r18 }}],
[19, {{ player.r19 }}],
[20, {{ player.r20 }}]
].slice(0, roundNumber + 1));
var options = {
hAxis: { title: 'Round', minValue: 0, maxValue: 20, multiples: 1, gridlines: { count: 20 }},
vAxis: { title: 'Price'},
title: 'Asset Price'
};
var chart = new google.visualization.LineChart(document.getElementById('chart_div'));
chart.draw(data, options);
}
</script>
In the function set_values(), I call a dictionary "price_dict" which would ideally come from reading the CSV file, picking a random "ID" which would pull 20 rows from the CSV file that all have that ID, and then create a dictionary from those rows that includes key:value pairs like "Round:PriceMovement" (e.g., {1:45.7, 2:14.2, 3:108.9...}. That is the part I am struggling with. I read through the documentation on reading CSV files and possibly using an ExtraModel class but nothing I've tried has worked. Any tips or example games that do this? I tried finding the Stroop task as the documentation suggested but I couldn't find any that utilize a CSV.
#2 by ckormylo
I think I may have figured it out. Instead of using dictionaries, I just assign all asset change variables (a1-a20) in the creating_session function. The HTML code slices the data on round number anyways so I realized there's no reason I can't assign all 20 rounds from the get go. There may be a more efficient way to do this but for now it seems to work. See code below.
**********************************
class Constants(BaseConstants):
name_in_url = 'Game'
players_per_group = None
num_rounds = 20
class Subsession(BaseSubsession):
pass
def creating_session(subsession: Subsession):
import csv
f = open(__name__ + '/MarketData.csv')
reader = list(csv.DictReader(f))
players = subsession.get_players()
for i in range(len(players)):
import random
player = players[i]
random_id = random.randint(1, 275)
filtered_data = [row for row in reader if row['ID'] == str(random_id)]
for j in range(1, Constants.num_rounds + 1):
exec(f"player.r{j} = float(filtered_data[{j - 1}]['AssetChange'])")
class Group(BaseGroup):
pass
class Player(BasePlayer):
r1 = models.FloatField()
r2 = models.FloatField()
r3 = models.FloatField()
r4 = models.FloatField()
r5 = models.FloatField()
r6 = models.FloatField()
r7 = models.FloatField()
r8 = models.FloatField()
r9 = models.FloatField()
r10 = models.FloatField()
r11 = models.FloatField()
r12 = models.FloatField()
r13 = models.FloatField()
r14 = models.FloatField()
r15 = models.FloatField()
r16 = models.FloatField()
r17 = models.FloatField()
r18 = models.FloatField()
r19 = models.FloatField()
r20 = models.FloatField()