Related
I have an error when trying to parse a value from JSON file.
Below the function:
var dt = new Date(Math.round(+new Date()));
var dt_full = (dt.getFullYear().toString() + '-' + (dt.getMonth()+1).toString() + '-' + dt.getDate().toString() + '-' + dt.getHours().toString() + '-' + dt.getMinutes().toString() + '-' + dt.getSeconds().toString())
var p = JSON.parse(msg.payload);
var C1 = p.C1;
msg.topic = "INSERT INTO mytable (id,date,index) VALUES (NULL, '"+dt_full+"', '"+C1+"')";
return msg;
I get following error:
SyntaxError: Unexpected token E in JSON at position 0
Following json file:
{
"product": "product name",
"status": "Success",
"C1": 1,
"C2": 1,
"C3": 1,
"C4": 0,
"C5": 0,
"C6": 0,
"C7": 0,
"C8": 0,
"C9": 0,
"C10": 0,
"C11": 0,
"C12": 0,
"C13": 0,
"C14": 0,
"C15": 0,
"C16": 0
}
First, there is no need to run JSON.parse(msg.payload) in the function node, you should just include a JSON node before the function node and it will parse the string in msg.payload to an object.
Secondly, For that error the msg.payload is not the JSON string you think it is. You should attach a Debug node to the output of the node before the function node to see exactly what the input actually is.
As it is that is all we can actually say from the information in the question.
I am filtering a range based on a condition. The condition is not always the same so I wanted to add is as a parameter to my filter function. My error comes when I call the custom filter function while passing through my additional it no longer looks at each individual item in the array and instead just the whole array.
function myFunction() {
var arr = [[1, 3, 1], [2, 3, 1], [1, 3, 2]];
myInt = 1;
return arr.getValues().filter(isMyInt(arr.getValues(), myInt));
}
function isMyInt(arr, myInt) {
return arr[0] == myInt;
}
In this example my desired result would be [[1, 3, 1], [1, 3, 2]].
Try this:
function myFunction() {
Logger.log([[1, 3, 1], [2, 3, 1], [1, 3, 2]].filter(r => r[0] == 1));
}
Execution log
2:23:11 PM Notice Execution started
2:23:12 PM Info [[1.0, 3.0, 1.0], [1.0, 3.0, 2.0]]
2:23:13 PM Notice Execution completed
So I made up this game, but I'm not able to find a good strategy to always win.
It's very similar to the original 3×3 Tic-Tac-Toe; but with changes.
So you draw a 5×5 board. Then each player takes turns putting a cross and circle. We then count the "scores".
This is a completed game that I drew. The scores are made by counting every 3-in-a-row strike. So for example in the top row, cross player gets 1 point.
You then do the counting horizontally, vertically, and both ways diagonally; for each row, column and diagonal.
For a 4-in-a-row, you get two points, as you can look at it as 2 different 3-in-a-rows. Similarly, a 5-in-a-row would get 3 points.
In the example game, cross wins as it get 9 whereas circle gets only 7.
I play this a lot; but it's always hard to tell where to put your next move. I've noticed that starting first gives you a significant advantage. To compensate for this, I lower the points of the player who started first by one.
Is it possible to brute force a computer to learn the best move for every game?
Thanks in advance!
Side note: If someone can program this as a simple game with random computer moves, that'd be great. I'm just getting into programming and I'm having a hard time figuring how to do it.
Brute forced
The snippet below will brute force all end games for player X and player O
There are 33,542,145 permutations to test of which ~ 5,000,000 are valid end games. To prevent the page locking up it splits the task into groups of 250,000 permutations
Best score for X is 16 and for O is 14. Run the snippet to see example end game layout and other details.
I did not include any handicap.
This can only do end games as it uses bit fields to keep performance high. However bit fields have no room of empty board positions.
It can be optimized to do both players at the same time by inverting the bits for each game permutation
const tag = (tag, props = {}) => Object.assign(document.createElement(tag), props);
const append = (par, ...sibs) => sibs.reduce((p, sib) => (p.appendChild(sib), p), par);
const log = (el, data, add = true) => add ? append(el, tag("div", {textContent: data.toString()})) : el.textContent = data.toString();
const scores = {
[0b00111] : 1,
[0b01110] : 1,
[0b11100] : 1,
[0b11101] : 1,
[0b10111] : 1,
[0b01111] : 2,
[0b11110] : 2,
[0b11111] : 3,
};
const rotateMat = [
0, 5, 10, 15, 20,
1, 6, 11, 16, 21,
2, 7, 12, 17, 22,
3, 8, 13, 18, 23,
4, 9, 14, 19, 24
];
const diagonMat = [
2, 8, 14, -1, -1,
1, 7, 13, 19, -1,
0, 6, 12, 18, 24,
5, 11, 17, 23, -1,
10, 16, 22, -1, -1,
];
const diagonMatUp = [
10, 6, 2, -1, -1,
15, 11, 7, 3, -1,
20, 16, 12, 8, 4,
21, 17, 13, 9, -1,
22, 18, 14,-1, -1,
];
function transform(board, matrix) {
var i = 25, b = 0;
while (i--) { matrix[i] > -1 && (board & (1 << matrix[i])) && (b |= 1 << i) }
return b;
}
function scoreLines(board) {
var i = 5, score = 0, l = 0;
while (i--) { score += scores[(board >> (i * 5)) & 0b11111] ?? 0 }
return score;
}
function score(board) {
return scoreLines(board) +
scoreLines(transform(board, rotateMat)) +
scoreLines(transform(board, diagonMat)) +
scoreLines(transform(board, diagonMatUp));
}
function isValidGame(board, side) {
var c = 0, i = 25, bits = side + 1;
while (i-- && c < bits) { (board & (1 << i)) && c++ }
return c === side;
}
function showBoard(board, score, side) {
var i = 5;
log(games, "------------------------");
log(games, "End game score: " + score + " player: " + (side===13 ? "X" : "O"));
log(games, "Example end game");
while (i--) {
const line = ((board >> (i * 5)) & 0b11111).toString(2).padStart(5, "0");
const lined = side === 13 ?
line.replace(/1/g,"X").replace(/0/g,"O") :
line.replace(/1/g,"O").replace(/0/g,"X");
log(games, lined);
}
}
function brute(side = 13) {
function doSet(i) {
var ii = 251357;
while (i >= min && ii--) {
if (isValidGame(i, side)) {
gameCount ++;
const s = score(i);
if (s >= maxScore) {
if (s > maxScore) {
bestEndGames.length = 0
game = i;
}
maxScore = s;
bestEndGames.push(i);
}
}
i--;
}
if (i >= min) {
setTimeout(doSet, 8, i);
log(progress, status + " is: " + maxScore + " tested: " + ((max - min) - (i - min)) + " of " + (max - min) + " permutations", false);
} else {
log(games, status + " is: " + maxScore + " of " + gameCount + " end games");
log(games, "Number of end games with best score: " + bestEndGames.length);
showBoard(game, maxScore, side);
if (side === 13) { setTimeout(brute, 1000, 12) }
else { log(progress, "Done", false) }
}
}
var game, gameCount = 0;
var maxScore = 0;
const bestEndGames = [];
const status = "Best score player: " + (side===13 ? "X" : "O");
const [min, max] = side === 13 ? [0b1111111111111, 0b1111111111111000000000000] : [0b111111111111, 0b1111111111110000000000000];
doSet(max)
}
brute(13);
<div id="progress"></div>
<div id="games"></div>
To score a game the next snippet will do so. A bit of a hack, enter game into input fields and will spit out scores.
const tag = (tag, props = {}) => Object.assign(document.createElement(tag), props);
const append = (par, ...sibs) => sibs.reduce((p, sib) => (p.appendChild(sib), p), par);
const log = (el, data, add = true) => add ? append(el, tag("div", {textContent: data.toString()})) : el.textContent = data.toString();
const scores = {
[0b00111] : 1,
[0b01110] : 1,
[0b11100] : 1,
[0b11101] : 1,
[0b10111] : 1,
[0b01111] : 2,
[0b11110] : 2,
[0b11111] : 3,
};
const rotateMat = [
0, 5, 10, 15, 20,
1, 6, 11, 16, 21,
2, 7, 12, 17, 22,
3, 8, 13, 18, 23,
4, 9, 14, 19, 24
];
const diagonMat = [
2, 8, 14, -1, -1,
1, 7, 13, 19, -1,
0, 6, 12, 18, 24,
5, 11, 17, 23, -1,
10, 16, 22, -1, -1,
];
const diagonMatUp = [
10, 6, 2, -1, -1,
15, 11, 7, 3, -1,
20, 16, 12, 8, 4,
21, 17, 13, 9, -1,
22, 18, 14,-1, -1,
];
function transform(board, matrix) {
var i = 25, b = 0;
while (i--) { matrix[i] > -1 && (board & (1 << matrix[i])) && (b |= 1 << i) }
return b;
}
function scoreLines(board) {
var i = 5, score = 0, l = 0;
while (i--) { score += scores[(board >> (i * 5)) & 0b11111] ?? 0 }
return score;
}
function score(board) {
return scoreLines(board) +
scoreLines(transform(board, rotateMat)) +
scoreLines(transform(board, diagonMat)) +
scoreLines(transform(board, diagonMatUp));
}
function isValidGame(board, side, asStr) {
var c = 0, i = 25, bits = side + 1;
while (i-- && c < bits) { (
(asStr[24-i] !== "-" && asStr[24-i] !== " ") && board & (1 << i)) && c++
}
return [c <= side, c];
}
function showBoard(board, asStr) {
var i = 0;
var j = 0;
while (i < 5) {
const line = ((board >> ((4-i) * 5)) & 0b11111).toString(2).padStart(5, "0");
const lined = line.replace(/1/g,"X").replace(/0/g,"O");
var str = "";
j = 0;
while (j < 5) {
str += (asStr[i * 5 + j] !== "-" && asStr[i * 5 + j] !== " ") ? lined[j] : ".";
j++;
}
log(games, str);
i++;
}
}
gameVal1.addEventListener("input", testGame);
gameVal2.addEventListener("input", testGame);
gameVal3.addEventListener("input", testGame);
gameVal4.addEventListener("input", testGame);
gameVal5.addEventListener("input", testGame);
function testGame() {
var board = gameVal1.value.slice(0,5).padEnd(5, "-");
board += gameVal2.value.slice(0,5).padEnd(5, "-");
board += gameVal3.value.slice(0,5).padEnd(5, "-");
board += gameVal4.value.slice(0,5).padEnd(5, "-");
board += gameVal5.value.slice(0,5).padEnd(5, "-");
board = board.replace(/[^OX\- ]/gi,"-");
const X = eval("0B" + board.replace(/X/gi,"1").replace(/O|-| /gi,"0"));
const O = eval("0B" + board.replace(/X|-| /gi,"0").replace(/O/gi,"1"));
const [vx, movesX] = isValidGame(X, 13, board);
const [vo, movesY] = isValidGame(O, 12, board);
vx && log(resultX, "Player X score: " + score(X) + " moves: " + movesX, false);
vo && log(resultO, "Player O score: " + score(O) + " moves: " + movesY, false);
games.innerHTML = "";
showBoard(X, board);
}
testGame()
input {
font-family: monospace;
font-size: large;
}
.fixFont {
font-family: monospace;
font-size: large;
}
#games {
position: absolute;
top: 28px;
left: 80px;
border: 1px solid black;
padding: 0px 3px;
letter-spacing: 3px;
}
#resultX {
position: absolute;
top: 40px;
left: 160px;
}
#resultO {
position: absolute;
top: 60px;
left: 160px;
}
<div class="fixFont">
Enter "x" "x" "O" or "o". Empty slots "-" or space<br>
<input type="text" id="gameVal1" value="XXXXX" size="5"><br>
<input type="text" id="gameVal2" value="XXXXO" size="5"><br>
<input type="text" id="gameVal3" value="XXXXO" size="5"><br>
<input type="text" id="gameVal4" value="OOOOO" size="5"><br>
<input type="text" id="gameVal5" value="OOOOO" size="5"><br>
<div id="resultX"></div>
<div id="resultO"></div>
<div id="games"></div>
</div>
I have some page with tables and 1 img that I want to create a button to make it a pdf.
The problem is, it's hebrew (utf-8 encoded).
Is there any way to do it?
I tried to use jsPDF but it's dosen't support hebrew.
Basicly what I want to make is a button that will create a pdf file that I will send via email as attachment.
Any suggestions?
Thank you!
This is what I've tried:
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.min.js"></script>
<script>
function demoFromHTML() {
var pdf = new jsPDF('p', 'pt', 'letter');
source = $('#content')[0];
specialElementHandlers = {
// element with id of "bypass" - jQuery style selector
'#bypassme': function (element, renderer) {
// true = "handled elsewhere, bypass text extraction"
return true
}
};
margins = {
top: 80,
bottom: 60,
left: 40,
width: 522
};
pdf.fromHTML(
source, // HTML string or DOM elem ref.
margins.left, // x coord
margins.top, { // y coord
'width': margins.width, // max width of content on PDF
'elementHandlers': specialElementHandlers
},
function (dispose) {
pdf.save('Test.pdf');
}, margins
);
}
</script>
Run Code
<div id="content">
HTML HERE
</div>
I recommend you to use this fpdf tool it is very simple to use.
Here there is a demo of my code
if(isset($_POST['pdf'])){
require('fpdf/fpdf.php');
$sname = $_POST['sname'];
$emailid = $_POST['emailid'];
$joindate = $_POST['joindate'];
$contact = $_POST['contact'];
$birthdate = $_POST['birthdate'];
$about = $_POST['about'];
$today = date("Y");
$pdf = new FPDF();
$pdf -> AddPage();
$pdf->Image('logo.png',85,6,40);
// Line break
$pdf->Ln(20);
// Arial bold 15
$pdf->SetFont('Arial','',15);
// Move to the right
$pdf->Cell(80);
// Title
$pdf->Cell(30,10,'Module '.$today,0,0,'C');
$pdf->Ln(10);
// Line break
$pdf->Ln(20);
$pdf->SetTextColor(0,0,0,1);
$w = $pdf->GetStringWidth($contact)+60;
$pdf->SetX((170-$w)/2);
$pdf->Cell(40, 10, 'Name:', 0, 0, 'L');
$pdf->Cell($w, 10, $sname, 0, 1, 'R');
$pdf->Ln(10);
$pdf->SetX((170-$w)/2);
$pdf->Cell(40, 10, 'Birth Date:', 0, 0, 'L');
$pdf->Cell($w, 10, $birthdate, 0, 1, 'R');
$pdf->Ln(10);
$pdf->SetX((170-$w)/2);
$pdf->Cell(40, 10, 'Telephone:', 0, 0, 'L');
$pdf->Cell($w, 10, $contact, 0, 1, 'R');
$pdf->Ln(10);
$pdf->SetX((170-$w)/2);
$pdf->Cell(40, 10, 'Email:', 0, 0, 'L');
$pdf->Cell($w, 10, $emailid, 0, 1, 'R');
$pdf->Ln(10);
$pdf->SetX((170-$w)/2);
$pdf->Cell(40, 10, 'Date of Join:', 0, 0, 'L');
$pdf->Cell($w, 10, $joindate, 0, 0, 'R');
$pdf->Ln(30);
$pdf->SetX((170-$w)/2);
$pdf->Cell(40, 10, '', 0, 0, 'R');
$pdf->Cell($w, 10, 'Signature:______________', 0, 0, 'R');
$pdf->Output('I',"Module {$today} of {$sname}.pdf");
}
I have a scatter plot made using plotly.py and I would like to color certain points in the scatter plot with a different color based on a certain condition. I have attached a sample code below :
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import plot
data = [4.1, 2.1, 3.1, 4.4, 3.2, 4.1, 2.2]
trace_1 = go.Scatter(
x = [1, 2, 3, 4, 5, 6, 7],
y = data
)
layout = go.Layout(
paper_bgcolor='rgb(255,255,255)',
plot_bgcolor='rgb(229,229,229)',
title = "Sample Plot",
showlegend = False,
xaxis = dict(
mirror = True,
showline = True,
showticklabels = True,
ticks = 'outside',
gridcolor = 'rgb(255,255,255)',
),
yaxis = dict(
mirror = True,
showline = True,
showticklabels = False,
gridcolor = 'rgb(255,255,255)',
),
shapes = [{
'type': 'line',
'x0': 1,
'y0': 4,
'x1': len(data),
'y1': 4,
'name': 'First',
'line': {
'color': 'rgb(147, 19, 19)',
'width': 1,
'dash': 'longdash'
}
},
{
'type': 'line',
'x0': 1,
'y0': 3,
'x1': len(data),
'y1': 3,
'line': {
'color': 'rgb(147, 19, 19)',
'width': 1,
'dash': 'longdash'
}
}
]
)
fig = dict(data = [trace_1], layout = layout)
plot(fig, filename = "test_plot.html")
Here's the output Output Scatter plot
Here the long dashed horizontal lines have corresponding x values 4 & 3 respectively. As one can see, points 1, 2, 4, 6 and 7 lie outside the dashed lines. Is there a way to color them differently based on the condition (x > 3) and (x<4).
Here's a reference to something I found while searching for a solution :
Python Matplotlib scatter plot: Specify color points depending on conditions
How can I achieve this in plotly.py ?
You can accomplish this by using a numeric array to specify the marker color. See https://plot.ly/python/line-and-scatter/#scatter-with-a-color-dimension.
Adapting your particular example to display red markers below 3, green markers above 4, and gray markers between 3 and 4:
import plotly.graph_objs as go
from plotly.offline import init_notebook_mode, iplot
init_notebook_mode()
data = [4.1, 2.1, 3.1, 4.4, 3.2, 4.1, 2.2]
color = [
-1 if v < 3 else 1 if v > 4 else 0
for v in data
]
colorscale = [[0, 'red'], [0.5, 'gray'], [1.0, 'green']]
trace_1 = go.Scatter(
x = [1, 2, 3, 4, 5, 6, 7],
y = data,
marker = {'color': color,
'colorscale': colorscale,
'size': 10
}
)
layout = go.Layout(
paper_bgcolor='rgb(255,255,255)',
plot_bgcolor='rgb(229,229,229)',
title = "Sample Plot",
showlegend = False,
xaxis = dict(
mirror = True,
showline = True,
showticklabels = True,
ticks = 'outside',
gridcolor = 'rgb(255,255,255)',
),
yaxis = dict(
mirror = True,
showline = True,
showticklabels = False,
gridcolor = 'rgb(255,255,255)',
),
shapes = [{
'type': 'line',
'x0': 1,
'y0': 4,
'x1': len(data),
'y1': 4,
'name': 'First',
'line': {
'color': 'rgb(147, 19, 19)',
'width': 1,
'dash': 'longdash'
}
},
{
'type': 'line',
'x0': 1,
'y0': 3,
'x1': len(data),
'y1': 3,
'line': {
'color': 'rgb(147, 19, 19)',
'width': 1,
'dash': 'longdash'
}
}
]
)
fig = dict(data = [trace_1], layout = layout)
iplot(fig)
Hope that helps!