I am programming an experiment on Otree in which players type in their names and participate in a competition on who donate the most threes. The trees are entered via a form field. Round number is a predefined variable. And every player gets an id when he enters the experiment by default (starting from 1)
I already programmed the whole code and it works with up to 5 participants, but now I should program it for up to 8 participants. When I try to enter the number of participants on Otree, I receive the error message "index error: list index out of range".
Error occurs in the line matrix[p.id_in_group - 1][0] = p.name
matrix[p.id_in_group - 1][self.round_number] = p.cumulative_donated_trees
so I guess the initialization of the matrix is wrong?
I just want to have a Matrix with 2 columns: names and trees (and index column of course) and n rows (n = number of players)```
models.py:
class Donation(Page):
try:
form_model = 'player'
form_fields = ['donation']
def vars_for_template(self):
names = []
trees = []
sortedtrees = []
anzahlspalten = 0
for p in self.subsession.get_players():
if self.round_number == 1:
matrix[p.id_in_group - 1][0] = p.name
matrix[p.id_in_group - 1][self.round_number] = p.cumulative_donated_trees
for i in range(0, Constants.number_of_players):
names.append(matrix[i][0])
trees.append(matrix[i][self.round_number])
sortedtrees = sorted(trees, reverse=True)
anzahlspalten = len(sortedtrees)
for l in range(0, anzahlspalten):
if self.player.cumulative_donated_trees == sortedtrees[l]:
self.player.current_position = str(l + 1)
models.py:
name = models.StringField(label="Your first name:")
transcribed_text = models.LongStringField()
levenshtein_distance = models.IntegerField()
guthaben = models.CurrencyField(initial=c(0))
cumulative_guthaben = models.CurrencyField()
cumulative_donation = models.FloatField(null=True)
right_answer = models.BooleanField()
right_answer_text = models.StringField()
treatmentgroup = models.StringField()
donation = models.FloatField(min=c(0))
no_trees = models.FloatField(initial=0.0)
cumulative_donated_trees = models.FloatField()
current_position = models.StringField()
spielstand = models.StringField()
Treceback:
File "c:\users\wiwi-admin\appdata\local\programs\python\python37\lib\site-packages\otree\views\abstract.py" in get_context_data
338. user_vars = self.vars_for_template()
File "C:\Users\Wiwi-Admin\Desktop\Backup Version 2 - Competition WITHIN Treatmentgroups\Master thesis code\__pycache__\oTree\my_environmental_surveyTG4\pages.py" in vars_for_template
252. matrix[p.id_in_group - 1][0] = p.name
Exception Type: IndexError at /p/tgv0j88z/my_environmental_surveyTG4/Donation/7/
Exception Value: list index out of range
Related
When I use splitter_freqy.py to split my .dat filem I meet the following problem.
line 5 name=str(sys.argv[position+1])
indexerror list index out of range
I use ubuntu and the command is
python3.6 splitter_freq.py abc.dat
This is the splitter_freq.py
import sys
arguments = len(sys.argv) - 1
position = 1
name = str(sys.argv[position+1])
while (arguments > position): # changed >= to > to avoid error
bench_freq_names = []
path0 = "./%s/"%name+sys.argv[position]
position = position+1
print("the input file is ",path0)
c_0 = open(path0,'r')
header=c_0.readline()
l_0 = c_0.readline()
w_0 = l_0.split()
bench_name = w_0[1]
freq_value = w_0[3]
path_out = path0.split("/")
path_out = path_out[-1].split(".")
print("the benchmark name is ",bench_name)
print("the freq value is ",freq_value)
bench_freq_names.append([bench_name,freq_value])
output_file = "./%s/"%name+path_out[0]+"_"+bench_name+"_"+freq_value+".txt"
m = open(output_file,'a')
print(header.rstrip('\n'),file=m)
print(l_0.rstrip('\n'),file=m)
for l_0 in c_0: #read lines one by one
w_0 = l_0.split()
if (w_0[1] == bench_name and w_0[3] == freq_value):
print(l_0.rstrip('\n'),file=m)
else: #new_bench_name or new freq_value
m.close() #close file
bench_name = w_0[1] #update bench
freq_value = w_0[3] #update freq
print("the benchmark name is ",bench_name)
print("the freq value is ",freq_value)
output_file = "./%s/"%name+path_out[0]+"_"+bench_name+"_"+freq_value+".txt"
m = open(output_file,'a')
if [bench_name,freq_value] not in bench_freq_names:
bench_freq_names.append([bench_name,freq_value])
print(header.rstrip('\n'),file=m)
print(l_0.rstrip('\n'),file=m)
c_0.close()
m.close()
I am using Django 3.2
I am dynamically calculating field values for an item that can be rated.
Here is a snippet of my code:
self.ratings_count = F('ratings_count') + 1
self.ratings_total = F('ratings_total') + rating_value
self.ratings_average = F('ratings_total') / F('ratings_count')
self.last_rated = timezone.now()
self.save() # Divide by zero error here (no records exist in Db)
I could trivially get around this by not using F fields (as a kludge - with attendant race conditions). My question is - how do I implement the desired behaviour, whilst using F expressions?
The 1st solution is to save the value of ratings_count & ratings_total before using it in the division operation, like that:
self.ratings_count = F('ratings_count') + 1
self.ratings_total = F('ratings_total') + rating_value
self.save(update_fields=['self.ratings_total', 'self.ratings_count']) # try to remove `self` if there are a problme
self.ratings_average = F('ratings_total') / F('ratings_count')
self.last_rated = timezone.now()
self.save(update_fields=['ratings_average', 'last_rated'])
the 2nd solution is:
self.ratings_count = F('ratings_count') + 1
self.ratings_total = F('ratings_total') + rating_value
if self.ratings_count == 0 and self.ratings_total == 0:
self.ratings_average = rating_value
else:
self.ratings_average = (F('ratings_total') + rating_value) / (F('self.ratings_count')+1)
self.last_rated = timezone.now()
self.save()
everyone.
I have some problems with calculating gcskews in python.
My 2 major inputs are fasta file and bed file.
Bed file has columns of gn(0), gene_type(1), gene name(2), chromosome(3), strand(4), num(5), start(6).(These numbers are index numbers in python.) Then I am trying to use some functions which can calculate gcskews of sense and antisense strand from the start site of each gene. The window is 100bp and these are the functions.
import re
import sys
import os
# opening bed file
content= []
with open("gene_info.full.tsv") as new :
for line in new :
content.append(line.strip().split())
content = content[1:]
def fasta2dict(fil):
dic = {}
scaf = ''
seq = []
for line in open(fil):
if line.startswith(">") and scaf == '':
scaf = line.split(' ')[0].lstrip(">").replace("\n", "")
elif line.startswith(">") and scaf != '':
dic[scaf] = ''.join(seq)
scaf = line.split(' ')[0].lstrip(">").replace("\n", "")
seq = []
else:
seq.append(line.rstrip())
dic[scaf] = ''.join(seq)
return dic
dic_file = fasta2dict("full.fa")
# functions for gc skew
def GC_skew_up(strand, loc, seq, window = 100) : # need -1 for index
values_up = []
loc = loc - 1
if strand == "+" :
sp_up = seq[loc - window : loc]
g_up = sp_up.count('G') + sp_up.count('g')
c_up = sp_up.count('C') + sp_up.count('c')
try :
skew_up = (g_up - c_up) / float(g_up + c_up)
except ZeroDivisionError:
skew_up = 0.0
values_up.append(skew_up)
elif strand == "-" :
sp_up = seq[loc : loc + window]
g_up = sp_up.count('G') + sp_up.count('g')
c_up = sp_up.count('C') + sp_up.count('c')
try :
skew_up = (c_up - g_up) / float(g_up + c_up)
except ZeroDivisionError:
skew_up = 0.0
values_up.append(skew_up)
return values_up
def GC_skew_dw(strand, loc, seq, window = 100) :
values_dw = []
loc = loc - 1
if strand == "+" :
sp_dw = seq[loc : loc + window]
g_dw = sp_dw.count('G') + sp_dw.count('g')
c_dw = sp_dw.count('C') + sp_dw.count('c')
try :
skew_dw = (g_dw - c_dw) / float(g_dw + c_dw)
except ZeroDivisionError:
skew_dw = 0.0
values_dw.append(skew_dw)
elif strand == "-" :
sp_dw = seq[loc - window : loc]
g_dw = sp_dw.count('G') + sp_dw.count('g')
c_dw = sp_dw.count('C') + sp_dw.count('c')
try :
skew_dw = (c_dw - g_dw) / float(g_dw + c_dw)
except ZeroDivisionError:
skew_dw = 0.0
values_dw.append(skew_dw)
return values_dw
As I said, I want to calculate the gcskews for 100bp of strands from the start site of genes.
Therefore, I made codes that get the chromosome name from the bed file and get the sequence data from the Fasta file.
Then according to gene name and strand information, I expected that codes will find the correct start site and gcskew for 100bp window will be calculated.
However, when I run this code, gcskew of - strand is wrong but + strand is correct. (I got correct gcskew data and I used it.)
Gcskews are different from the correct data, but I don't know what is the problem.
Could anyone tell me what is the problem of this code?
Thanks in advance!
window = 100
gname = []
up = []
dw = []
for match in content :
seq_chr = dic_file[str(match[3])]
if match[4] == "+" :
strand = match[4]
new = int(match[6])
sen_up = GC_skew_up(strand, new, seq_chr, window = 100)
sen_dw = GC_skew_dw(strand, new, seq_chr, window = 100)
gname.append(match[2])
up.append(str(sen_up[0]))
dw.append(str(sen_dw[0]))
if match[4] == "-" :
strand = match[4]
new = int(match[6])
an_up = GC_skew_up(strand, new, seq_chr, window = 100)
an_dw = GC_skew_dw(strand, new, seq_chr, window = 100)
gname.append(match[2])
up.append(str(an_up[0]))
dw.append(str(an_dw[0]))
tot = zip(gname, up, dw)
I need to find the engagement rate for each data row and then find the video title with the highest engagement rate.
'row' in the dict youtube_usa_videos consist of many elements of which the index for each element has been named. The problem arises when I try to set the condition as seen below which python gives 'division by zero' error message as there are some views that are zero in the data set.
Engagement rate = no. of comments / no. of views
#code below
highest_EGR = 0
for row in youtube_usa_videos:
comments = row [8]
views = row [5]
title = row [1]
if views != 0:
EGR = comments / views
else:
EGR = 0
If EGR > highest_EGR:
highest_EGR = EGR
top_vid = title
Can you help me clean my code such that the conditions will be met and the top video title and its engagement rate will be printed?
The code below works well.
Consider replacing If with if
highest_EGR = 0
youtube_usa_videos = [['t1',12,45],['t2',34,12],['t3',2,123]]
TITLE_OFFSET = 0
VIEWS_OFFSET = 1
COMMENTS_OFFSET = 2
for row in youtube_usa_videos:
comments = row [COMMENTS_OFFSET]
views = row [VIEWS_OFFSET]
title = row [TITLE_OFFSET]
if views != 0:
EGR = comments / views
else:
EGR = 0
if EGR > highest_EGR:
highest_EGR = EGR
top_vid = title
print('highest_EGR: {}'.format(highest_EGR))
# or using max and lambda
max_egr = max(youtube_usa_videos,key=lambda vid:vid[COMMENTS_OFFSET] / vid[VIEWS_OFFSET] if vid[VIEWS_OFFSET] else 0)
print('video with max eger: {}'.format(max_egr))
output
highest_EGR: 61.5
video with max eger: ['t3', 2, 123]
highest_EGR = 0
for row in youtube_usa_videos:
comments = row [8]
views = row [5]
title = row [1]
if int (views) > 0:
EGR = int (comments) / int (views)
if EGR > highest_EGR:
highest_EGR = EGR
top_vid = title
print (top_vid, highest_EGR)
Okay I simply changed 'if views != 0:' to 'if views > 0:' and removed 'else:'
I am trying to create a list objects that holds data about professional golfers. The different data points are golfer name and putting percentages from different distances. I want to sort this list of objects by name once all the data has been entered for every player object. The list of these objects is called PlayerNumber. When I try to sort PlayerNumber by attribute 'name'. I get an error stating that 'int' has no attribute and I am not sure why PlayerNumber is being referred to as an integer and not a list.
Any help would be appreciated. Here is the code:
import operator
import numpy as np
import statistics
import matplotlib.pyplot as plt
from colour import Color
from bs4 import BeautifulSoup
import urllib3
############### ACCESS WEBPAGES ####################
def makeSoup(url):
http = urllib3.PoolManager()
response = http.request('GET', url)
soupdata = BeautifulSoup(response.data)
return soupdata
siteURL = []
for i in range(7):
siteURL.append(i)
siteURL[0] = ''
siteURL[1] = 'http://www.pgatour.com/stats/stat.408.html' #>25
siteURL[2] = 'http://www.pgatour.com/stats/stat.407.html' #20-25
siteURL[3] = 'http://www.pgatour.com/stats/stat.406.html' #15-20
siteURL[4] = 'http://www.pgatour.com/stats/stat.405.html' #10-15
siteURL[5] = 'http://www.pgatour.com/stats/stat.404.html' #5-10
siteURL[6] = 'http://www.pgatour.com/stats/stat.02427.html' #3-5
############### ACCESS TABLE DATA ###################
def row_number(soupdata):
for row in table.findAll('tr'):
tot_row = row
return tot_row
def parse_table(soupdata):
currRank = []
prevRank = []
playerName = []
rounds = []
pctMake = []
attempts = []
puttsMade = []
table = soupdata.find('tbody')
tot_row = 0
for row in table.findAll('tr'):
#for col in row.findAll('td'):
col = row.find_all('td')
#column_1 = col[0]
#currRank.append(column_1)
#column_2 = col[1]
#prevRank.append(column_2)
column_3 = col[2].text
column_3.strip()
playerName.append(column_3)
#column_4 = col[3]
#rounds.append(column_4)
column_5 = col[4].text
pctMake.append(column_5)
#column_6 = col[5]
#attempts.append(column_6)
#column_7 = col[6]
#puttsMade.append(column_7)
tot_row += 1
#return currRank, prevRank, playerName, rounds, pctMake, attempts, puttsMade
return playerName, pctMake, tot_row
"""
>25 ft: distance1
20-25 ft: distance2
15-20 ft: distance3
10-15 ft: distance4
5-10 ft: distance5
3-5 ft: distance6
"""
############### CLASS DEFINITION ###################
class Player:
id_list={}
def __init__(self,name, id, dis1=0.0, dis2=0.0, dis3=0.0, dis4=0.0, dis5=0.0, dis6=0.0):
self.name = name
self.dis1 = dis1
self.dis2 = dis2
self.dis3 = dis3
self.dis4 = dis4
self.dis5 = dis5
self.dis6 = dis6
self.id = id
Player.id_list[self.name] = self # save the id as key and self as he value
def addDis1(self,distance1):
self.dis1 = float(distance1)
def addDis2(self,distance2):
self.dis2 = float(distance2)
def addDis3(self,distance3):
self.dis3 = float(distance3)
def addDis4(self,distance4):
self.dis4 = float(distance4)
def addDis5(self,distance5):
self.dis5 = float(distance5)
def addDis6(self,distance6):
self.dis6 = float(distance6)
def displayPlayer(self):
print("Player: ", self.name, '\n'
">25 Ft %: ", self.dis1, '\n'
"20-25 Ft %: ", self.dis2, '\n'
"15-20 Ft %: ", self.dis3, '\n'
"10-15 Ft %: ", self.dis4, '\n'
"5-10 Ft %: ", self.dis5, '\n'
"3-5 Ft %: ", self.dis6, '\n')
#classmethod
def lookup_player_name_by_id(cls, name):
try:
return cls.id_list[name] # return the instance with the id
except KeyError: # error check for if id does not exist
raise KeyError("No user with id %s" % str(id))
############### DATA POPULATION ###################
PlayerNumber=[]
for i in range(0,195):
PlayerNumber.append(i)
for i in range(1,7):
soupdata = makeSoup(siteURL[i])
playerName, pctMake, tot_row = parse_table(soupdata)
for x in range(0,tot_row):
#PlayerNumber.append(x)
name = playerName[x]
name = name.replace("\xa0", " ")
name = name.replace("\n", "")
if i == 1:
PlayerNumber[x] = Player(name, x)
Player.addDis1(PlayerNumber[x],pctMake[x])
if i == 2:
val = Player.lookup_player_name_by_id(name)
Player.addDis2(PlayerNumber[val.id],pctMake[x])
if i == 3:
val = Player.lookup_player_name_by_id(name)
Player.addDis3(PlayerNumber[val.id],pctMake[x])
if i == 4:
val = Player.lookup_player_name_by_id(name)
Player.addDis4(PlayerNumber[val.id],pctMake[x])
if i == 5:
val = Player.lookup_player_name_by_id(name)
Player.addDis5(PlayerNumber[val.id],pctMake[x])
if i == 6:
val = Player.lookup_player_name_by_id(name)
Player.addDis6(PlayerNumber[val.id],pctMake[x])
PlayerNumber.sort(key = operator.attrgetter("name"))
#PlayerNumber[2].displayPlayer()
I'm using Python 3.4 spyder IDE. I'm relatively new to python as an FYI.
Thanks!
It isn't that PlayerNumber is being referred to as an integer, but rather that PlayerNumber is a list of integers, and every element of that list (and integer) doesn't has an attribute "name", which sort() is trying to access (in order to sort them).
Edit:
To elaborate, the second to last line in your sample:
PlayerNumber.sort(key = operator.attrgetter("name"))
is trying to sort PlayerNumber, using the comparison function: operator.attrgetter("name"), which means it must call that function on each element of PlayerNumber to get its rank in the sorted array. That is why you are trying to grab a .name attribute from the integers in PlayerNumber.