// "New World" by Tharakesh Aravindan
// https://ancientbrain.com/edit.world.php?world=3654434791
// Simple AI Translation Accuracy Tester (English → Spanish)
// Using OpenAI (requires key) and MyMemory (no key needed, browser-safe)
// Author: Tharakesh Aravindan, Date: 23/11/2025
// Ancient Brain World for empirical API evaluation
// My OpenAi API Key: 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
// Credits & References:
// - OpenAI API: https://openai.com/
// - MyMemory API: https://mymemory.translated.net/doc/spec.php
// - Ancient Brain coding platform: https://ancientbrain.com/
// - Example World reference: https://run.ancientbrain.com/run.php?world=2850716357 (World: Chat with GPT Model)
// - Mozilla Developer Network (MDN) JavaScript documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
// - Humphrys, M. (2025). Bringing AI APIs into the classroom with a JavaScript coding site. IJIET Vol.15, No.2. https://humphryscomputing.com/Publications/london.ijiet.pdf
// All project code is original except for referenced sample Worlds and official API documentation.
const DATA = [
{id:1, en:"The cat is sitting on the table.", es:"El gato está sentado en la mesa."},
{id:2, en:"She will arrive tomorrow.", es:"Ella llegará mañana."},
{id:3, en:"I don't like cold weather.", es:"No me gusta el clima frío."},
{id:4, en:"Can you help me with this problem?", es:"¿Puedes ayudarme con este problema?"},
{id:5, en:"He bought three red apples.", es:"Compró tres manzanas rojas."},
{id:6, en:"I have been learning Spanish for two years.", es:"He estado aprendiendo español durante dos años."},
{id:7, en:"We met at the station at six o'clock.", es:"Nos conocimos en la estación a las seis."},
{id:8, en:"Water boils at 100 degrees Celsius.", es:"El agua hierve a 100 grados Celsius."},
{id:9, en:"My favorite sport is football.", es:"Mi deporte favorito es el fútbol."},
{id:10, en:"The quick brown fox jumps over the lazy dog.", es:"El rápido zorro marrón salta sobre el perro perezoso."}
];
// ---- HTML UI ----
let html = `
<h1>AI Translation Accuracy Tester</h1>
<p>Compare two AI translation APIs: OpenAI (requires key) and MyMemory (no key needed).</p>
<label>OpenAI API Key:</label>
<input id='openaiKey' placeholder='sk-...' style='width:100%'><br><br>
<label>Select test sentence:</label>
<select id='testSelect'></select><br><br>
<button id='runBtn'>Run Both Translators</button>
<button id='runAllBtn'>Run Full Dataset</button><br><br>
<h2>Expected Answer:</h2>
<pre id='expected'>(choose a test)</pre>
<h2>OpenAI Result:</h2>
<pre id='openaiOut'>-</pre>
<p>Match: <span id='openaiPass'>-</span></p>
<h2>MyMemory Result:</h2>
<pre id='mymemOut'>-</pre>
<p>Match: <span id='mymemPass'>-</span></p>
<h2>Metrics:</h2>
<div id='metrics'></div>
`;
document.write(html);
// ---- Populate dropdown ----
const select = document.getElementById('testSelect');
DATA.forEach(t => {
const opt = document.createElement('option');
opt.value = t.id;
opt.textContent = `${t.id}: ${t.en}`;
select.appendChild(opt);
});
const expectedEl = document.getElementById('expected');
const openaiOut = document.getElementById('openaiOut');
const mymemOut = document.getElementById('mymemOut');
const openaiPass = document.getElementById('openaiPass');
const mymemPass = document.getElementById('mymemPass');
const metrics = document.getElementById('metrics');
function getTestById(id){ return DATA.find(d=>d.id==id); }
function normalize(s){ return String(s||'').normalize('NFKD').replace(/[\u0300-\u036f]/g,'').toLowerCase().replace(/[^\w]+/g,' ').trim(); }
function tokenOverlap(a,b){ const A=normalize(a).split(/\s+/),B=normalize(b).split(/\s+/); const common=A.filter(x=>B.includes(x)).length; return common/Math.max(A.length,B.length); }
function setExpected(){ const t=getTestById(select.value); expectedEl.textContent=t.es; }
select.addEventListener('change', setExpected);
setExpected();
// ---- Run OpenAI ----
async function callOpenAI(text,key){
try{
const prompt=`Translate the following English sentence into Spanish. Return only the translation:\n"${text}"`;
const resp=await fetch('https://api.openai.com/v1/chat/completions',{
method:'POST',
headers:{'Content-Type':'application/json','Authorization':`Bearer ${key}`},
body:JSON.stringify({
model:'gpt-4o-mini',
messages:[{role:'user',content:prompt}],
max_tokens:200,
temperature:0
})
});
const j=await resp.json();
return j?.choices?.[0]?.message?.content || JSON.stringify(j);
}catch(e){ return 'ERROR:'+e; }
}
// ---- Run MyMemory Translation ----
async function callMyMemory(text){
try{
// language pair: en|es for English->Spanish
const url =
"https://api.mymemory.translated.net/get?q=" +
encodeURIComponent(text) + "&langpair=en|es";
const resp = await fetch(url);
if (!resp.ok) throw new Error('API request failed with status: ' + resp.status);
const j = await resp.json();
// The translation is usually in j.responseData.translatedText
return j?.responseData?.translatedText || JSON.stringify(j);
}catch(e){
return 'ERROR:' + e;
}
}
// ---- Run one test ----
async function runTest(t,openaiKey,display=true){
const expected = t.es;
const openaiText = await callOpenAI(t.en,openaiKey);
const mymemText = await callMyMemory(t.en);
const openaiScore = tokenOverlap(openaiText, expected);
const mymemScore = tokenOverlap(mymemText, expected);
const openaiPassBool = (normalize(openaiText) === normalize(expected)) || openaiScore >= 0.8;
const mymemPassBool = (normalize(mymemText) === normalize(expected)) || mymemScore >= 0.8;
if (display) {
openaiOut.textContent = openaiText;
mymemOut.textContent = mymemText;
openaiPass.textContent = openaiPassBool ? 'PASS' : 'FAIL';
openaiPass.className = openaiPassBool ? 'pass' : 'fail';
mymemPass.textContent = mymemPassBool ? 'PASS' : 'FAIL';
mymemPass.className = mymemPassBool ? 'pass' : 'fail';
metrics.innerHTML = `OpenAI overlap: ${openaiScore.toFixed(2)} — MyMemory overlap: ${mymemScore.toFixed(2)}`;
}
return { openaiText, mymemText, openaiPass: openaiPassBool, mymemPass: mymemPassBool };
}
// ---- Button listeners ----
document.getElementById('runBtn').addEventListener('click', async () => {
const key = document.getElementById('openaiKey').value.trim();
if (!key) { alert('Paste OpenAI key'); return; }
const t = getTestById(select.value);
await runTest(t, key);
});
document.getElementById('runAllBtn').addEventListener('click', async () => {
const key = document.getElementById('openaiKey').value.trim();
if (!key) { alert('Paste OpenAI key'); return; }
const results = [];
for (const t of DATA) {
const r = await runTest(t, key, false);
results.push({ id: t.id, openaiPass: r.openaiPass, mymemPass: r.mymemPass });
}
const openaiAcc = results.filter(r => r.openaiPass).length / results.length;
const mymemAcc = results.filter(r => r.mymemPass).length / results.length;
metrics.innerHTML = `OpenAI accuracy: ${(openaiAcc * 100).toFixed(1)}%<br>MyMemory accuracy: ${(mymemAcc * 100).toFixed(1)}%<br><br>Per-item results:<br><pre>${JSON.stringify(results, null, 2)}</pre>`;
});