我正在分析总统候选人的演讲。我有一个包含以下变量的数据文件:
> names(cl.context)
[1] "id" "category" "statement" "nchar" "polarity"
statement
变量由每个属于三个category
的句子填充。 polarity
范围从-1到1,反映句子是否具有正偏差,中性或负偏差
我在p5中尝试做的是当用户在画布中单击鼠标时,按类别显示语句,随机x,y放置。这些陈述本身根据其极性着色
我终于达到了开发者控制台不会抛出任何错误并绘制画布的程度。但是当我在画布中单击时,没有任何反应。没有陈述。
我对JavaScript很陌生,因为它没有抛出错误信息,我无法解决问题所在。希望在这里提供一些建议。
我的p5代码:
var clContext;
var x;
var y;
const STATEMENTS = 118, CATEGORY = 3, QTY = STATEMENTS/CATEGORY | 0,
POLARITY = 3,
statements = Array(STATEMENTS), inds = Array(CATEGORY), polarity = Array(POLARITY);
//load the table of Clinton's words and frequencies
function preload() {
clContext = loadTable("cl_context.csv", "header");
}
function setup() {
createCanvas(647, 400);
background(51);
// Calling noStroke once here to avoid unecessary repeated function calls
noStroke();
// iterate over the table rows
for(var i=0; i<clContext.getRowCount(); i++){
//- Get data out of the relevant columns for each row -//
var inds = clContext.get(i, "category");
var statements = clContext.get(i, "statement");
var polarity = clContext.get(i, "polarity")
}
for (let i = 0; i < statements; randomCategoryStates(i++));
// create your Statement object and add to
// the statements array for use later
inds[i] = new Statement();
console.info(inds);
}
function draw() {
if(mouseClicked == true){
for(var i=0; i<inds.length; i++) {
inds[i].display();
}
}
}
function mouseClicked() {
if((mouseX < width) && (mouseY < height)) {
randomCategoryStates(~~random(CATEGORY));
redraw();
return false;
}
}
// Function to display statements by a random category with each mouse click
function randomCategoryStates(group) {
let idx = inds[group], rnd;
while ((rnd = ~~random(QTY)) == idx);
inds[group] = rnd;
}
// Function to align statements, categories, and polarity
function Statement() {
this.x = x;
this.y = y;
this.xmax = 10;
this.ymax = 4;
this.cat = inds;
this.statement = statements;
this.polarity = polarity;
// set a random x,y position for each statement
this.dx = (Math.random()*this.xmax) * (Math.random() < .5 ? -1 : 1);
this.dy = (Math.random()*this.ymax) * (Math.random() < .5 ? -1 : 1);
}
// Attach pseudo-class methods to prototype;
// Maps polarity to color and x,y to random placement on canvas
Statement.prototype.display = function() {
this.x += this.dx;
this.y += this.dy;
var cols = map(this.polarity == -1, 205, 38, 38);
var cols = map(this.polarity == 0, 148, 0, 211);
var cols = map(this.polarity == 1, 0, 145, 205);
fill(cols);
textSize(14);
text(this.statement, this.x, this.y);
};
编辑:让我感到困惑的一件事是,我在处理论坛上使用此代码获得的帮助并没有在{{mouseClicked()
函数中调用draw
函数1}}函数,所以我补充说。不完全确定我是否正确地做了或者甚至是必要的。
答案 0 :(得分:1)
你的代码有很多。我将尝试通过所有事情,没有特别的顺序:
为什么需要这些变量?
var x;
var y;
我知道您认为您正在使用它们将位置传递给Statement
,但您从未设置过这些变量!让我们暂时摆脱它们,因为它们没有做任何事情。这会导致代码出错,但我们会在一秒钟内修复此错误。
看看这个循环:
for(var i=0; i<clContext.getRowCount(); i++){
//- Get data out of the relevant columns for each row -//
var inds = clContext.get(i, "category");
var statements = clContext.get(i, "statement");
var polarity = clContext.get(i, "polarity")
}
您在此处阅读CSV文件,但之后您无法对这些变量进行任何操作。然后你用这个来跟进:
for (let i = 0; i < statements; randomCategoryStates(i++));
// create your Statement object and add to
// the statements array for use later
inds[i] = new Statement();
注意循环之后的分号!这意味着inds[i] = new Statement()
行在外面循环,这没有任何意义。我也不知道你在randomCategoryStates(i++)
部分做了什么。
您需要将所有这些组合成一个循环:
for (var i = 0; i < clContext.getRowCount(); i++) {
var category = clContext.get(i, "category");
var statement = clContext.get(i, "statement");
var polarity = clContext.get(i, "polarity")
inds[i] = new Statement();
}
但这仍然没有任何意义,因为您永远不会将这些变量传递到您的Statement
课程中。所以,让我们来看看。
我只是添加一些评论:
function Statement() {
this.x = x; //when do you ever set the value of x?
this.y = y; //when do you ever set the value of y?
this.cat = inds; //cat is the array that holds all statements? What??
this.statement = statements; //statement is the statements array, but nothing is ever added to that array?
this.polarity = polarity; //when do you ever set the value of polarity?
正如您所看到的,您在这里所做的事情并没有多大意义。你需要改变这个构造函数,以便它需要参数,然后你需要传递这些参数。像这样:
function Statement(category, polarity, statement) {
this.category = category;
this.statement = statement;
this.polarity = polarity;
}
现在我们已经有了,我们可以将for循环中的行更改为:
inds[i] = new Statement(category, statement, polarity);
但这仍然没有意义。为什么你有单独的数组用于语句,类别和极性?你只是想要一个使用Statement
类的实例来保存它们的数组吗?因此,让我们摆脱inds
和polarity
变量,因为它们不能用于任何事情。
然后我们将该行更改为:
statements[i] = new Statement(category, polarity, statement);
我们还必须更改仍在使用inds
变量的其他地方,但我们还有其他问题。
让我们从您的draw()
功能开始:
function draw() {
if (mouseClicked == true) {
for (var i = 0; i < statements.length; i++) {
statements[i].display();
}
}
}
所以我猜你只想在按下鼠标时显示任何内容,没有按下鼠标时什么都不显示?我不确定这是否合理,但没关系。即便如此,此代码也没有意义,因为 mouseClicked
是一个函数,而不是一个变量。要确定是否按下了鼠标,您需要使用{{3}变量,你不需要== true
部分。
if (mouseIsPressed) {
我不知道这两个函数应该做什么:
function mouseClicked() {
if ((mouseX < width) && (mouseY < height)) {
randomCategoryStates(~~random(CATEGORY));
redraw();
return false;
}
}
// Function to display statements by a random category with each mouse click
function randomCategoryStates(group) {
let idx = statements[group],
rnd;
while ((rnd = ~~random(QTY)) == idx);
statements[group] = rnd;
}
有更简单的方法可以获取随机数据。我现在要删除它们,因为它们比它们值得更麻烦。我们可以稍后返回并添加随机逻辑。
现在,让我们看一下display()
课程中的Statement
函数:
Statement.prototype.display = function() {
this.x += this.dx;
this.y += this.dy;
var cols = map(this.polarity == -1, 205, 38, 38);
var cols = map(this.polarity == 0, 148, 0, 211);
var cols = map(this.polarity == 1, 0, 145, 205);
fill(cols);
textSize(14);
text(this.statement, this.x, this.y);
};
我们从未真正声明x
,y
,dx
或dy
变量,因此我们将它们添加到构造函数中:
this.x = random(width);
this.y = random(height);
this.dx = random(-5, 5);
this.dy = random(-5, 5);
返回display()
功能,这些行没有任何意义:
var cols = map(this.polarity == -1, 205, 38, 38);
var cols = map(this.polarity == 0, 148, 0, 211);
var cols = map(this.polarity == 1, 0, 145, 205);
为什么要将相同的变量声明3次?为什么要尝试将布尔值映射到数值?这没有任何意义。现在,让我们摆脱这些界限并简化你的逻辑:
if(this.polarity == -1){
fill(255, 0, 0);
}
else if(this.polarity == 1){
fill(0, 255, 0);
}
else{
fill(0, 0, 255);
}
这将使负极性为红色,正极性为绿色,中性极性为蓝色。
现在我们有了这个,我们实际上可以运行代码。当您按住鼠标时,您将看到您的语句随机显示和移动。但是,他们会快速填满您的屏幕,因为您无法清除旧框架。 每当您要清除旧框架时,都需要调用background()
函数。我们可能会在draw()
函数的开始处或{{1}内部执行此操作。在for循环之前的语句。
if(mouseIsPressed)
如果您进行了所有这些更改,那么您将有一个正常工作的计划。我愿意打赌它仍然没有完全符合您的要求。 您必须开始更简单。您的代码有点混乱,而且这是尝试一次编写整个程序而不是测试小的结果一次一块。 这就是我们要求mouseIsPressed
,的原因,因为调试这样的事情是非常痛苦的。你需要开始将目标缩小到更小的部分。
例如,如果你现在想要这样做,那么一次只出现一个语句,重新开始,只有一个简单的示例草图,它只显示一个硬编码语句。在您尝试将其集成到主程序之前,完美地运行。如果您希望按类别排序语句,那么重新开始使用更简单的示例草图,它只显示基于类别的语句,而不需要任何额外的逻辑。这样,如果您对某些特定内容有疑问,可以发布这些小代码,这将更容易为您提供帮助。
祝你好运。