Why's this happening? I've made a Python code editor to work on the web in Ace editor and Skulpt.js. Whenever I run this code:
a=[1,2,3,]
for a[-1] in a:
print(a[-1],end=",")
in the editor it shows this output:
1,2,3,
when it's actually supposed to show
1,2,2,
It shows 1,2,3, only on my editor. It works as 1,2,2, everywhere else. Here's the code:
<!DOCTYPE html>
<html>
<head>
<head>
<meta charset="utf-8" />
<title>Python IDE on webpage - example</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<!--jquery-->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!--skulpt-->
<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>
<!--import ace-->
<script
src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.12/ace.js"
integrity="sha512-GZ1RIgZaSc8rnco/8CXfRdCpDxRCphenIiZ2ztLy3XQfCbQUSCuk8IudvNHxkRA3oUg6q0qejgN/qqyG1duv5Q=="
crossorigin="anonymous"
></script>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Jost:wght@200&display=swap" rel="stylesheet">
<!--setting height is important-->
<style>
.editor, .output {
height: 60vh;
}
.run-button, .stop-button {
height: 50px;
width: 100px;
border: none;
border-radius: 10px;
color: #fff;
background-color: black;
position: absolute;
top: 10px;
left: 50%;
font-family: Jost;
transform: translateX(-50%);
animation: pagination 1s ease 0s infinite;
}
.logo {
height: 50px;
width: 100px;
border: none;
border-radius: 10px;
color: #fff;
background-color: black;
position: absolute;
top: 10px;
left: 10%;
font-family: Jost;
font-weight: 400px;
transform: translateX(-50%);
padding-right: 30px;
animation: pagination 1s ease 0s infinite;
}
.logs {
width: 100%;
color: #000;
font-family: monospace;
display: flex;
justify-content: center;
}
@keyframes pagination {
0% {
top: 10px;
}
50% {
top: 15px;
}
100% {
top: 10px;
}
}
</style>
</head>
<body>
<br><br><br><br>
<div style="display: flex; flex-wrap: wrap; border:1px solid black;">
<!--editor container: setting width to is important-->
<div style="width: 50%;">
<div class="editor">print(100)</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;">
<div class="logo">
<div style="display: flex; flex-direction: row;">
<p>Logo</p>
</div>
</div>
<button
type="button"
class="run-button"
onclick="runit($($(this).parent().siblings()[0]).children()[0], $($(this).parent().siblings()[1]).children()[0])"
>
Run code
</button>
<button
type="button"
class="stop-button"
onclick="stopit()"
style="display: none;"
>
Stop code
</button>
</div>
</div>
<div class="logs"></div>
<script>
function lineCount(watchamacallit) {
return watchamacallit.split(/\r*\n/).length;
};
const Range = ace.require("ace/range").Range;
$(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");
// editor.session.setValue(decodeURIComponent(window.location.href.split('code=')[1]) != "undefined" ? decodeURIComponent(window.location.href.split('code=')[1]) : "print('Hello, world')"); //you can set value from xhr here
$(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();
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);
// output.insert(startTime - endTime)
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();
},
function (err) {
output.insert("<" + err.toString() + ">");
$(".run-button").show();
$(".stop-button").hide();
}
);
document.querySelector('.logs').innerHTML = `Time taken to execute: ${endTime-startTime} milliseconds\nNumber of lines:${lineCount(prog)}`
}
function stopit() {
Sk.execLimit = 1; //stop all previous execution
Sk.timeoutMsg = function () {
Sk.execLimit = Number.POSITIVE_INFINITY;
return "Program Terminated";
};
}
</script>
</body>
</html>
It's like this here. I thought it might be that Skulpt released a new version, but I see 1.0.3, the one I'm using, is the latest.