我使用 Skulpt 在浏览器中创建了一个 Python 编辑器。当我输入代码时
a=[1,2,3,]
for a[-1] in a:
print(a[-1],end=",")
1, 2, 3,
当它应该返回时,它会输入它1, 2, 2,
。
如果您不明白这段代码的作用,它只是查看列表的第一个元素并将其分配给a[-1]
,这意味着它将第一个元素分配给列表的最后一个元素。因此,在循环迭代结束时,列表如下所示1, 2, 1
:
在循环的第二次迭代中for
,它将 for 循环的第二个元素分配给列表的最后一个元素,这意味着它正在查看列表的第二个元素并将其分配给列表的最后一个元素was 1
, to 2
, 使列表看起来像1, 2, 2
本次迭代结束时的样子。
在第三次迭代中,它查看列表的第三个和最后一个元素并将其分配给自己,使看起来像的列表再次1, 2, 2
看起来像1, 2, 2
。我在 Skulpt 的主页上查看了编辑器,它在那里运行良好。出于某种原因,它不会发生在我的身上。
这是编辑器的 JavaScript 代码:
var kodeEditor = document.querySelector(".kodeEditor");
kodeEditor.innerHTML = `<div class="wrapper">
<!--editor container: setting width to is important-->
<div style="width: 50%;">
<div class="editor">${kodeEditor.innerHTML}</div>
</div>
<!--output container: setting width to is important-->
<div style="width: 50%;">
<div class="output"></div>
</div>
<!--button group-->
<div style="margin-top: 10px;">
<button
type="button"
class="run-button"
onclick="runit($($(this).parent().siblings()[0]).children()[0], $($(this).parent().siblings()[1]).children()[0])"
>
Run
</button>
<button
type="button"
class="stop-button"
onclick="stopit()"
style="display: none;"
>
Stop code
</button>
</div>
</div>`;
function lineCount(watchamacallit) {
return watchamacallit.split(/\r*\n/).length;
}
const Range = ace.require("ace/range").Range;
const langTools = ace.require("ace/ext/language_tools");
$(document).ready(function () {
//editor
$(".editor").each(function (index) {
const editor = ace.edit(this);
editor.setTheme("ace/theme/nord_dark");
editor.session.setMode("ace/mode/python");
// enable autocompletion and snippets
editor.setOptions({
enableBasicAutocompletion: true,
enableSnippets: true,
enableLiveAutocompletion: true,
});
var staticWordCompleter = {
getCompletions: function (editor, session, pos, prefix, callback) {
var wordList = ["foo", "bar", "baz"];
callback(
null,
wordList.map(function (word) {
return {
caption: word,
value: word,
meta: "static",
};
})
);
},
};
$(this).data("aceObject", editor);
});
//console
$(".output").each(function (index) {
const output = ace.edit(this);
output.session.setMode("ace/mode/plain_text");
output.renderer.setShowGutter(false);
output.setReadOnly(true);
$(this).data("aceObject", output);
output.prevCursorPosition = output.getCursorPosition();
//restrict cursor after the printed part during input
output.selection.on("changeCursor", function () {
const currentPosition = output.getCursorPosition();
if (currentPosition.row < output.prevCursorPosition.row) {
output.selection.moveCursorToPosition(output.prevCursorPosition);
} else if (currentPosition.row == output.prevCursorPosition.row) {
if (currentPosition.column < output.prevCursorPosition.column) {
output.selection.moveCursorToPosition(output.prevCursorPosition);
}
}
});
//prevent selection by double triple click during input
output.selection.on("changeSelection", function () {
const anchorPosition = output.selection.getSelectionAnchor();
const leadPosition = output.selection.getSelectionLead();
if (
anchorPosition.row < output.prevCursorPosition.row ||
leadPosition.row < output.prevCursorPosition.row
) {
output.selection.clearSelection();
} else if (
anchorPosition.row == output.prevCursorPosition.row ||
leadPosition.row == output.prevCursorPosition.row
) {
if (
anchorPosition.column < output.prevCursorPosition.column ||
leadPosition.column < output.prevCursorPosition.column
) {
output.selection.clearSelection();
}
}
});
});
//prevent selection by drag and drop during input
$(".output").on(
"dragstart ondrop dbclick",
(e) => {
e.stopImmediatePropagation();
e.stopPropagation();
e.preventDefault();
return false;
},
false
);
});
function builtinRead(x) {
if (
Sk.builtinFiles === undefined ||
Sk.builtinFiles["files"][x] === undefined
)
throw "File not found: '" + x + "'";
return Sk.builtinFiles["files"][x];
}
function runit(editorElem, outputElem) {
startTime = performance.now();
$(".run-button").hide(); //hiding every runButton and turning into stop button
$(".stop-button").show();
const editor = $(editorElem).data("aceObject");
const output = $(outputElem).data("aceObject");
const prog = editor.session.getValue();
globalThis.program = editor.session.getValue();
if (startRun) {
startRun();
}
console.log(prog);
output.session.setValue("");
Sk.pre = "output";
Sk.configure({
inputfun: function () {
output.setReadOnly(false);
// the function returns a promise to give a result back later...
return new Promise(function (resolve, reject) {
$(outputElem).on("keydown", function (e) {
if (e.keyCode == 13) {
e.preventDefault();
output.setReadOnly(true);
$(outputElem).off("keydown");
output.navigateLineEnd();
const inputText = output.session.getTextRange(
new Range(
output.prevCursorPosition.row,
output.prevCursorPosition.column,
output.getCursorPosition().row,
output.getCursorPosition().column
)
);
resolve(inputText);
console.log(inputText);
output.insert("\n");
output.prevCursorPosition = output.getCursorPosition();
output.session.setUndoManager(new ace.UndoManager()); //resets undo stack
}
});
$(".stop-button").on("click", function (e) {
$(outputElem).unbind();
output.setReadOnly(true);
return resolve();
});
});
},
output: function (text) {
endTime = performance.now();
output.insert(text);
globalThis.executed = text;
if (text.search("Error") != -1) {
alert("amigo!");
}
console.log(text);
output.prevCursorPosition = output.getCursorPosition();
output.session.setUndoManager(new ace.UndoManager());
},
read: builtinRead,
__future__: Sk.python3,
execLimit: Number.POSITIVE_INFINITY,
});
//(Sk.TurtleGraphics || (Sk.TurtleGraphics = {})).target = "mycanvas"; //for future pupose
var myPromise = Sk.misceval.asyncToPromise(function () {
return Sk.importMainWithBody("<stdin>", false, prog, true);
});
myPromise.then(
function (mod) {
console.log("success");
$(".run-button").show();
$(".stop-button").hide();
globalThis.success = true;
if (endRun) {
endRun();
}
},
function (err) {
globalThis.success = false;
if (endRun) {
endRun();
}
output.insert(err.toString());
$(".run-button").show();
$(".stop-button").hide();
}
);
}
function stopit() {
Sk.execLimit = 1; //stop all previous execution
Sk.timeoutMsg = function () {
Sk.execLimit = Number.POSITIVE_INFINITY;
return "Program Terminated";
};
}
HTML 中 Skulpt 的链接,不包括上述 JavaScript 文件的链接:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@s524797336/skulpt@1.0.3/skulpt.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@s524797336/skulpt@1.0.3/skulpt-stdlib.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js" integrity="sha512-GZ1RIgZaSc8rnco/8CXfRdCpDxRCphenIiZ2ztLy3XQfCbQUSCuk8IudvNHxkRA3oUg6q0qejgN/qqyG1duv5Q==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.11/ext-language_tools.js"></script>
你能帮忙吗?我被困住了。