我正在尝试做一些在Python(2.7.6)中可能不那么困难的事情,但我无法解决问题。这是用于fMRI实验(特别是在expyriment中)。我有一个看起来像这样的csv:
level,string,key
1,string11,1
1,string12,0
1,string13,1
2,string21,1
2,string22,1
2,string23,0
有20个级别(1:20),csv大约有5000个记录。我想要做的是从特定级别的第二列出现一个字符串(起始级别是预先确定的)。因此,例如,我们测试了一个主题并确定它们将从第5级开始。从第5级呈现随机字符串(例如,“牛是动物”)。主题按下一个真/假的按钮(在“键”栏中回答 - 1/0)。棘手的一点是,每4个连续的正确答案,级别增加1,不正确的答案将级别减少1。
时间/效率有点重要,所以我认为csv可以提前解析,然后在实验期间工作的部分只是访问按级别存储的数据。我看过嵌套的词典,似乎不对。也许是嵌套列表?我有点超出我的深度。我在bash中写了一个工作示例,以防比我的解释更清楚。
#!/bin/bash
csv="file.csv"
level="5"
ilevel="0"
counter="1"
while [ "$counter" -le 10 ]; do
stim=$(awk -F',' -v l="$level" '{if($1==l) print $2","$3}' "$csv"|sort -R|head -n1)
stim1=$(echo "$stim"|cut -d',' -f1)
stim2=$(echo "$stim"|cut -d',' -f2)
read -p "$stim1 (t/f): " ANS
if [[ "$stim2" == "1" && "$ANS" == "t" || "$stim2" == "0" && "$ANS" == "f" ]]; then #if correct
ilevel=$(echo "scale=2;$ilevel+.25"|bc) #add .25 to ilevel counter
if [[ "$ilevel" == "1.00" ]]; then
if [[ "$level" < "20" ]]; then
level=$(echo "$level+1"|bc) #increase level
fi
ilevel=0
fi
else
if [[ "$level" > "1" ]]; then #if incorrect
level=$(echo "$level-1"|bc) #decrease level
fi
ilevel=0
fi
let "counter += 1"
done
bash脚本仅用于工作示例的目的 - 计数器,打印到屏幕,用户反馈......在现实中处理的方式都不同,并且已经完成。我只需要弄清楚csv的排序并操纵关卡。提前感谢任何建议。
答案 0 :(得分:1)
要对字符串进行分组,请使用dict并使用random.choice选择随机字符串:
from collections import defaultdict
import csv
from random import choice
d = defaultdict(list)
with open("in.csv") as f:
next(f)
r = csv.reader(f)
for row in r:
d[int(row[0])].append(row[1])
level = 2
ch = choice(d[level])
print(ch)
string21
如果您需要答案/第2栏:
from collections import defaultdict
d = defaultdict(defaultdict)
with open("in.csv") as f:
next(f)
r = csv.reader(f)
for row in r:
d[int(row[0])][row[1]] = row[2]
from pprint import pprint as pp
pp(dict(d))
level = 2
ch = choice(list(d[level]))
ans = d[level][ch]
print(ch,ans)
输出:
# main dict keys are levels, nested dict contain key/value pairing
# question and answer
{1: defaultdict(None, {'string11': '1', 'string12': '0', 'string13': '1'}),
2: defaultdict(None, {'string21': '1', 'string23': '0', 'string22': '1'})}
主要的dict键是级别,嵌套的dicts保存所有级别字符串,它们是嵌套dicts的键,值3是答案的第3列。
如果您正在使用gui,那么您的逻辑将类似于以下内容,但显然使用您的gui方法:
level = 2
streak = 0
# current level questions
level_choice = list(d[level])
while True:
# pick random string/question
ch = choice(level_choice)
# correct answer
ans = d[level][ch]
inp = raw_input("ask questions using ch")
# if answer is correct increment streak
if inp == ans:
streak += 1
else:
# else it is wrong, drop a level and update variables
level -= 1
streak = 0
level_choice = list(d[level])
# if we have four in a row, up level ad again update variables
if streak == 4:
level += 1
streak = 0
level_choice = list(d[level])
显然必须有一个地方,许多错误的答案意味着水平达到0,这可能是打破的时间,你必须决定的逻辑。如果您不想重复提问,那么您必须将它们从字典中删除。