Skip to main content

kNearestNeighbors

Nov 19, 2022CodeCatch
Loading...

More JavaScript Posts

Redux Setup

Mar 11, 2021C S

0 likes • 2 views

import { configureStore } from "@reduxjs/toolkit";
import { combineReducers } from "redux";
import profile from "./profile";
import auth from "./auth";
import alert from "./alert";
const reducer = combineReducers({
profile,
auth,
alert,
});
const store = configureStore({ reducer });
export default store;

retryPromise.js

Oct 20, 2023LeifMessinger

0 likes • 20 views

//Retries maxRetries number of times, meaning that if you have 0, then it'll run the function once.
async function retryPromise(promiseFn, maxRetries = 3, delayOffset = 0, delayRandomRange = 0) {
return new Promise((resolve, reject) => {
promiseFn()
.then(resolve, (error) => { //On error
if (maxRetries <= 0) {
return reject(error);
} else {
if(delayRandomRange * Math.random() + delayOffset < 1.0){
return retryPromise(promiseFn, maxRetries - 1, delayOffset, delayRandomRange).then(resolve, reject);
}else{
return new Promise((resolveTwo, rejectTwo) => {
setTimeout(() => {
return retryPromise(promiseFn, maxRetries - 1, delayOffset, delayRandomRange).then(resolveTwo, rejectTwo);
}, delayRandomRange * Math.random() + delayOffset);
}).then(resolve, reject);
}
}
});
});
}
//Tests for that function.
//Returns a function that will fail numTimes times, then will return aValue
function functionThatReturnsAFunctionThatFailsACoupleTimes(numTimes, aValue){
return async function(){
if(numTimes == 0){
return aValue;
}
numTimes--;
throw false;
};
}
const SMALL_NUMBER = 10;
function testTest(failNumberOfTimes){
let functionThatFailsACoupleTimes = functionThatReturnsAFunctionThatFailsACoupleTimes(failNumberOfTimes, true);
//Test my test
for(let i = 0; i < (failNumberOfTimes * 2); ++i){
function evalTest(val){
let testTestFailedReason = "";
if(val === undefined){
testTestFailedReason = "Test test returned undefined for some reason.";
}
if((i + 1) > failNumberOfTimes){
if(val === true){
//We're good
}else{
testTestFailedReason = "Test test didn't return true when it should have.";
}
}else{
if(val === false){
//We're good
}else{
testTestFailedReason = "Test test didn't return false when it should have.";
}
}
testTestFailedReason = testTestFailedReason || "Test test passed test case";
console.log(testTestFailedReason, "at index", i, "where the function returned", val);
}
functionThatFailsACoupleTimes().then(evalTest, evalTest)
};
}
testTest(SMALL_NUMBER);
let testCaseCounter = 1;
const throwsNoError = [
(val)=>{
if(val == true){
console.log("Passed test case " + (testCaseCounter++));
}else{
console.error("Unexpected return value", val);
}
},
()=>{
console.error("It wasn't supposed to fail!")
}
]
const throwsError = [
(val)=>{
console.error("It wasn't supposed to succeed!", val);
},
(val)=>{
if(val == false){
console.log("Passed test case " + (testCaseCounter++));
}else{
console.error("Unexpected return value", val);
}
}
];
//Runs SMALL_NUMBER times, because SMALL_NUMBER - 1 is the number of retries after the first one
let functionThatFailsACoupleTimes = functionThatReturnsAFunctionThatFailsACoupleTimes(SMALL_NUMBER - 1, true);
retryPromise(functionThatFailsACoupleTimes, SMALL_NUMBER - 1).then(...throwsNoError)
functionThatFailsACoupleTimes = functionThatReturnsAFunctionThatFailsACoupleTimes(SMALL_NUMBER - 1, true);
//Runs SMALL_NUMBER - 1 times, because SMALL_NUMBER - 2 is the number of retries after the first one
retryPromise(functionThatFailsACoupleTimes, SMALL_NUMBER - 2).then(...throwsError)
//Testing the delay. You'll have to wait a bit too.
functionThatFailsACoupleTimes = functionThatReturnsAFunctionThatFailsACoupleTimes(SMALL_NUMBER - 1, true);
//Runs SMALL_NUMBER times, because SMALL_NUMBER - 1 is the number of retries after the first one
retryPromise(functionThatFailsACoupleTimes, SMALL_NUMBER - 1, 500, 500).then(...throwsNoError)
functionThatFailsACoupleTimes = functionThatReturnsAFunctionThatFailsACoupleTimes(SMALL_NUMBER - 1, true);
//Runs SMALL_NUMBER - 1 times, because SMALL_NUMBER - 2 is the number of retries after the first one
retryPromise(functionThatFailsACoupleTimes, SMALL_NUMBER - 2, 500, 500).then(...throwsError)

Mee6 Spam Calculator

Mar 10, 2022LeifMessinger

0 likes • 1 view

//Use at https://mee6.xyz/leaderboard/732262089447702588
//Higher the spammy stat, the more spammy that person is.
//This is because mee doesn't give experience to people who post more comments in a minute.
function statBlock(title, value){
let elm = document.createElement("div");
elm.className = "leaderboardPlayerStatBlock";
let titleElm = document.createElement("div");
titleElm.className = "leaderboardPlayerStatName";
titleElm.textContent = title;
let valueElm = document.createElement("div");
valueElm.className = "leaderboardPlayerStatValue";
valueElm.textContent = value;
elm.appendChild(titleElm);
elm.appendChild(valueElm);
elm.remove = function(){
this.parentElement.removeChild(this);
}
return elm;
}
for(let player of Array.from(document.getElementsByClassName("leaderboardPlayer"))){
if(player.spamminess) player.spamminess.remove();
let messages = null;
let experience = null;
const statBlockArray = Array.from(player.querySelectorAll(".leaderboardPlayerStatBlock"));
for(let statBlock of statBlockArray){
const statName = statBlock.querySelector(".leaderboardPlayerStatName").textContent;
const text = statBlock.querySelector(".leaderboardPlayerStatValue").textContent;
const number = ((text.includes("k"))? (text.replace("k","") * 1000.0) : +(text));
if(statName.includes("MESSAGES")){
messages = number;
}else if(statName.includes("EXPERIENCE")){
experience = number;
}
}
const stats = player.querySelector(".leaderboardPlayerStats");
const messagesElement = stats.firstChild;
const spamminess = ((messages/experience)*2000.0).toFixed(2);
player.spamminess = stats.insertBefore(statBlock("SPAMMINESS", spamminess), messagesElement);
}

Scrape twitter

Sep 2, 2023LeifMessinger

0 likes • 12 views

//Allegedly never tested on the twitter website
function scrapeScreen(){
let articles = Array.from(document.getElementsByTagName("article"));
let results = [];
for(let tweet of articles){
const isAnAd = Array.from(tweet.querySelectorAll("span")).map((e)=>e.textContent).includes("Ad");
if(isAnAd){
//console.log(tweet, "is an ad. Skipping...");
continue;
}
const userName = tweet.querySelector("[data-testid='User-Name'] > div:nth-child(2) > div > div")?.textContent;
const tweetContent = tweet.querySelector("[data-testid='tweetText']")?.textContent;
const timeStamp = tweet.querySelector("time")?.getAttribute("datetime");
const tweetLink = tweet.querySelector("time")?.parentElement?.getAttribute("href");
if((!userName) || (!tweetContent)) continue;
results.push({
username: userName,
tweetText: tweetContent,
timeStamp: timeStamp,
tweetLink: tweetLink
});
}
return results;
}
let scraped = scrapeScreen();
setInterval(()=>{
scraped = scraped.concat(
scrapeScreen().filter((tweet)=>{
for(let scrapedTweet of scraped){
if(scrapedTweet.username == tweet.username && scrapedTweet.tweetText == tweet.tweetText) return false;
}
return true;
})
);
}, 500); //Scrape everything on the screen twice a second
window.scrollIntervalId = setInterval(function(){
window.scrollBy(0, 1000);
}, 500); //Scroll for me
//http://bgrins.github.io/devtools-snippets/#console-save
(function(console){
console.save = function(data, filename){
if(!data) {
console.error('Console.save: No data')
return;
}
if(!filename) filename = 'console.json'
if(typeof data === "object"){
data = JSON.stringify(data, undefined, '\t')
}
var blob = new Blob([data], {type: 'text/json'}),
e = document.createEvent('MouseEvents'),
a = document.createElement('a')
a.download = filename
a.href = window.URL.createObjectURL(blob)
a.dataset.downloadurl = ['text/json', a.download, a.href].join(':')
e.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null)
a.dispatchEvent(e)
}
})(console)
setTimeout(()=>{
clearTimeout(window.scrollIntervalId);
delete window.scrollIntervalId;
console.save(scraped, "TwitterScrape" + Date.now() + ".json");
}, 60 * 1000 * 20); //Twenty minutes

Horizontal legend (d3.js)

Dec 17, 2024shaiRos

0 likes • 2 views

const rectSize = 15; // Size of the color box
const spacing = 5; // Space between legend items
let legend = canvas.append('g').attr('class','chart-legend')
.attr('transform', `translate(${0}, ${height + 3})`);
// Sample data for the legend
const legendData = [
{ label: 'low', color: '#1f77b4' },
{ label: 'medium', color: '#ff7f0e' },
{ label: 'high', color: '#2ca02c' },
{ label: 'very high', color: '#2ca02c' }
];
legend.selectAll('g')
.data(legendData)
.join('g')
.attr('class', 'legend-item')
.each(function (d, i) {
const legendItem = d3.select(this);
console.log(d.label)
console.log(d.label?.length)
let labelWidth = (d.label.length * 5) + 7 + 15
var bbox = legendItem.node().getBBox()
var width = bbox.width
console.log(width)
// Add rectangle for color
legendItem.append('rect')
.attr('width', rectSize)
.attr('height', rectSize)
.attr('fill', d.color);
// Add label
legendItem.append('text')
.attr('x', rectSize + spacing) // Position text to the right of the rectangle
.attr('y', rectSize / 2) // Align text vertically with the rectangle
.attr('dy', '.35em') // Adjust vertical alignment
.attr('text-anchor', 'start') // Align text to the start
.text(d.label)
.attr('fill', 'black'); // Optional: Text color
// legendItem.attr('transform', `translate(${i * (rectSize + spacing + labelWidth)}, 0)`) // Position each item horizontally
});
const legendItems_spacing = 12
var legendLength = 0
legend.selectAll('.legend-item').each(function(d,i) {
d3.select(this).attr('transform',function() {
var bbox = d3.select(this).node().getBBox()
var width = bbox.width
// if (width == 0) width = (d.text.length * 5) +15 // not in dom yet
let startingPosition = 0
if (i > 0) {
startingPosition = legendLength
}
legendLength += width + legendItems_spacing
// return `translate(${xx - (width + 30)},0$)`
return `translate(${startingPosition},0)`
})
})

geometric progression

Nov 19, 2022CodeCatch

0 likes • 0 views

const geometricProgression = (end, start = 1, step = 2) =>
Array.from({
length: Math.floor(Math.log(end / start) / Math.log(step)) + 1,
}).map((_, i) => start * step ** i);
geometricProgression(256); // [1, 2, 4, 8, 16, 32, 64, 128, 256]
geometricProgression(256, 3); // [3, 6, 12, 24, 48, 96, 192]
geometricProgression(256, 1, 4); // [1, 4, 16, 64, 256]