K Nithin Kumar Goud

Create your portfolio with ProoVCreate your portfolio with ProoV
ProoV
DE Verified work portfolio

ProoV Portfolio

K Nithin Kumar Goud

Electronics & Communication Engineering · Osmania University

View the ProoV leaderboard

Projects

Certified

Self-directed project

Frontend Engineering with Prediction Game

Junior Front-End Engineer · Software Engineering · July 2026

84/ 100

Built a complete World Cup prediction game end to end: rendered the tournament fixtures as interactive pick cards, scored picks with the exact 5/2/0 rubric, derived team attack/defense strengths from real historical results, and used those strengths to generate bot predictions. Also implemented a persistent ranked leaderboard and deployed the finished experience to a live Netlify URL.

Graded against

  • Scoring engine correctness30%
  • Prediction model genuinely from real data25%
  • Game completeness and leaderboard soundness25%
  • Shipped and shareable: live deployed URL20%

Passed · pass mark 60/100

What stood out6
  • Rendered the fixture board with one card per match and two numeric score inputs per card.
  • Implemented scorePick with correct handling for exact scores, same-result different-score cases, and draws.
  • Computed team strengths from a real-results sample and used those strengths inside botPredict rather than hard-coding outcomes.
  • Shipped a live https deployment on Netlify.
  • Leakage-Free Feature Engineering
  • Honest Model Evaluation
The work I submitted10 tasks

Lab Orientation

My solution
{"code":"<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <title>Predict the Cup</title>\n    <style>\n      body {\n        font-family: -apple-system, sans-serif;\n        background: #FDFCF7;\n        color: #0E1726;\n        padding: 32px;\n        margin: 0;\n      }\n      h1 {\n        color: #00C65A;\n        font-size: 32px;\n        margin: 0 0 12px 0;\n      }\n      p { color: #3F4B5F; margin: 0; }\n    </style>\n  </head>\n  <body>\n    <!-- TODO: change this title to something of your own -->\n    <h1>Prediction Game</h1>\n    <p>Welcome to your prediction game.</p>\n  </body>\n</html>","ranAt":"2026-07-26T10:01:56.247Z"}

Example Render Fixtures

My solution
{"code":"<!doctype html>\n<html><head>\n  <meta charset=\"utf-8\" />\n  <title>Worked example · render two matches</title>\n  <style>\n    body { font: 15px/1.4 system-ui; padding: 24px; background: #F7F8FA; }\n    .match { background: #fff; border: 1px solid #E4E8EE; border-radius: 12px;\n             padding: 14px; margin-bottom: 12px; max-width: 360px; }\n    .teams { font-weight: 800; color: #0E1726; margin-bottom: 8px; }\n    .picks { display: grid; grid-template-columns: 1fr auto 1fr; gap: 8px; align-items: center; }\n    input  { padding: 8px; border: 1px solid #E4E8EE; border-radius: 8px; text-align: center; }\n    .vs    { color: #6A7589; font-weight: 700; font-size: 12px; }\n  </style>\n</head><body>\n\n  <h1>My picks</h1>\n  <div id=\"board\"></div>\n\n  <script>\n    // (1) The data — a small 2-match sample so the loop is easy to see.\n    const SAMPLE_FIXTURES = [\n      { home: \"Germany\", away: \"Brazil\", date: \"2026-06-28\" },\n      { home: \"France\",  away: \"Spain\",  date: \"2026-06-29\" },\n    ];\n\n    // (2) Grab the empty box on the page we'll add cards to.\n    const board = document.getElementById(\"board\");\n\n    // (3) For each match, build a card and append it.\n    SAMPLE_FIXTURES.forEach((match) => {\n      const card = document.createElement(\"div\");\n      card.className = \"match\";\n      card.setAttribute(\"data-match\", match.home + \"-\" + match.away);\n\n      // (4) Team names + two score boxes (a \"vs\" between them).\n      card.innerHTML =\n        '<div class=\"teams\">' + match.home + ' vs ' + match.away + '</div>' +\n        '<div class=\"picks\">' +\n          '<input type=\"number\" min=\"0\" placeholder=\"0\" />' +\n          '<span class=\"vs\">vs</span>' +\n          '<input type=\"number\" min=\"0\" placeholder=\"0\" />' +\n        '</div>';\n\n      // (5) Add the finished card to the page.\n      board.appendChild(card);\n    });\n  </script>\n\n</body></html>","ranAt":"2026-07-26T10:02:18.540Z"}

Act1 Fixtures Form

My solution
{"code":"<!doctype html>\n<html>\n<head>\n  <meta charset=\"utf-8\" />\n  <title>Predict the Cup · my picks</title>\n\n  <style>\n    body {\n      font: 15px/1.45 system-ui, -apple-system, \"Segoe UI\", sans-serif;\n      padding: 24px;\n      background: #F7F8FA;\n      color: #0E1726;\n    }\n\n    h1 {\n      margin: 0 0 4px;\n      font-size: 22px;\n    }\n\n    .sub {\n      color: #6A7589;\n      font-size: 13px;\n      margin-bottom: 16px;\n    }\n\n    #board {\n      display: grid;\n      gap: 12px;\n      max-width: 640px;\n    }\n\n    .match {\n      background: #fff;\n      border: 1px solid #E4E8EE;\n      border-radius: 12px;\n      padding: 14px;\n    }\n\n    .meta {\n      color: #6A7589;\n      font-size: 11px;\n      text-transform: uppercase;\n      letter-spacing: 0.14em;\n      margin-bottom: 6px;\n    }\n\n    .teams {\n      font-weight: 800;\n      font-size: 15.5px;\n      margin-bottom: 8px;\n    }\n\n    .picks {\n      display: grid;\n      grid-template-columns: 1fr auto 1fr;\n      gap: 8px;\n      align-items: center;\n    }\n\n    .picks input {\n      padding: 9px;\n      border: 1px solid #E4E8EE;\n      border-radius: 8px;\n      text-align: center;\n      font: inherit;\n      font-weight: 700;\n      font-size: 15px;\n    }\n\n    .vs {\n      color: #6A7589;\n      font-weight: 700;\n      font-size: 12px;\n      text-align: center;\n    }\n\n    footer {\n      color: #6A7589;\n      font-size: 11px;\n      margin-top: 24px;\n      max-width: 640px;\n      line-height: 1.5;\n    }\n  </style>\n</head>\n\n<body>\n\n<h1>My picks</h1>\n<div class=\"sub\">2026 World Cup · Round of 32</div>\n\n<div id=\"board\"></div>\n\n<footer>\n  Independent learning project. Not affiliated with or endorsed by FIFA.\n  Fixtures snapshot: openfootball/worldcup.json (CC0-1.0).\n</footer>\n\n<script>\n\nconst FIXTURES = [\n  { home: \"Germany\", away: \"Mexico\", date: \"2026-06-28\", round: \"R32\" },\n  { home: \"Argentina\", away: \"Switzerland\", date: \"2026-06-29\", round: \"R32\" },\n  { home: \"France\", away: \"Portugal\", date: \"2026-06-30\", round: \"R32\" },\n  { home: \"Spain\", away: \"Uruguay\", date: \"2026-07-01\", round: \"R32\" },\n  { home: \"Brazil\", away: \"Japan\", date: \"2026-07-02\", round: \"R32\" },\n  { home: \"England\", away: \"Netherlands\", date: \"2026-07-03\", round: \"R32\" }\n];\n\nfunction renderFixtures() {\n\n  const board = document.getElementById(\"board\");\n\n  FIXTURES.forEach(function(match) {\n\n    const card = document.createElement(\"div\");\n    card.className = \"match\";\n\n    card.setAttribute(\"data-match\", match.home + \"-\" + match.away);\n\n    card.innerHTML =\n      '<div class=\"meta\">' +\n        match.round + \" · \" + match.date +\n      '</div>' +\n\n      '<div class=\"teams\">' +\n        match.home + \" vs \" + match.away +\n      '</div>' +\n\n      '<div class=\"picks\">' +\n        '<input type=\"number\" min=\"0\" placeholder=\"0\">' +\n        '<span class=\"vs\">vs</span>' +\n        '<input type=\"number\" min=\"0\" placeholder=\"0\">' +\n      '</div>';\n\n    board.appendChild(card);\n\n  });\n\n}\n\nrenderFixtures();\n\n</script>\n\n</body>\n</html>","ranAt":"2026-07-26T10:07:32.270Z","selfCheck":{"cases":[{"name":"FIXTURES const is in scope","pass":true,"detail":""},{"name":"One card per fixture (data-match)","pass":true,"detail":""},{"name":"Two number inputs per card","pass":true,"detail":""},{"name":"Team names visible on each card","pass":true,"detail":""}],"ranAt":"2026-07-26T10:07:32.270Z"},"passed":true,"attempt":1}

Act2 Scoring Function

My solution
{"code":"<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>scorePick · your turn</title>\n  </head>\n\n  <body>\n    <h1>scorePick · your turn</h1>\n\n    <pre id=\"out\" style=\"font-family:ui-monospace,Menlo,monospace;font-size:13px;white-space:pre-wrap\"></pre>\n\n    <script>\n      // Returns:\n      // 5 = exact score\n      // 2 = correct result\n      // 0 = wrong result\n\n      function scorePick(predicted, actual) {\n\n        // Exact score\n        if (\n          predicted.home === actual.home &&\n          predicted.away === actual.away\n        ) {\n          return 5;\n        }\n\n        // Determine predicted result\n        let predictedResult;\n\n        if (predicted.home > predicted.away) {\n          predictedResult = \"home\";\n        } else if (predicted.home < predicted.away) {\n          predictedResult = \"away\";\n        } else {\n          predictedResult = \"draw\";\n        }\n\n        // Determine actual result\n        let actualResult;\n\n        if (actual.home > actual.away) {\n          actualResult = \"home\";\n        } else if (actual.home < actual.away) {\n          actualResult = \"away\";\n        } else {\n          actualResult = \"draw\";\n        }\n\n        // Same result but different score\n        if (predictedResult === actualResult) {\n          return 2;\n        }\n\n        // Wrong result\n        return 0;\n      }\n\n      // Local sanity-check\n      const cases = [\n        { pred: { home: 2, away: 1 }, actual: { home: 2, away: 1 }, why: 'exact 2-1' },\n        { pred: { home: 3, away: 0 }, actual: { home: 1, away: 0 }, why: 'home win, wrong score' },\n        { pred: { home: 0, away: 1 }, actual: { home: 2, away: 0 }, why: 'wrong result' },\n        { pred: { home: 1, away: 1 }, actual: { home: 2, away: 2 }, why: 'both draws' },\n      ];\n\n      const out = document.getElementById('out');\n\n      out.textContent = cases\n        .map(c =>\n          `${c.pred.home}-${c.pred.away} vs ${c.actual.home}-${c.actual.away} -> ${scorePick(c.pred, c.actual)} // ${c.why}`\n        )\n        .join('\\n');\n    </script>\n\n  </body>\n</html>","ranAt":"2026-07-26T10:08:56.336Z","passed":true,"attempt":1,"selfCheck":null}

Act3 Compute Strength

My solution
{"passed":true,"attempt":1,"selfCheck":{"allPass":true,"failedNames":[]},"ranAt":"2026-07-26T10:09:55.526Z"}

Act3 House Bot

My solution
{"passed":true,"attempt":1,"selfCheck":{"allPass":true,"failedNames":[]},"ranAt":"2026-07-26T10:10:39.686Z"}

Act4 Leaderboard

My solution
{"code":"<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <title>Section 4 · the leaderboard</title>\n    <style>\n      body {\n        font-family: ui-sans-serif, system-ui, sans-serif;\n        padding: 20px;\n        max-width: 520px;\n        margin: 0 auto;\n      }\n\n      h1 {\n        font-size: 18px;\n        margin: 0 0 4px 0;\n      }\n\n      .sub {\n        color: #6B7280;\n        font-size: 12px;\n        margin: 0 0 14px 0;\n      }\n\n      table {\n        width: 100%;\n        border-collapse: collapse;\n      }\n\n      th,\n      td {\n        text-align: left;\n        padding: 8px 10px;\n        border-bottom: 1px solid #E5E7EB;\n        font-size: 14px;\n      }\n\n      th {\n        color: #6B7280;\n        font-size: 11px;\n        text-transform: uppercase;\n        letter-spacing: .06em;\n      }\n\n      .rank {\n        width: 36px;\n        color: #9CA3AF;\n        font-variant-numeric: tabular-nums;\n      }\n\n      .total {\n        text-align: right;\n        font-weight: 700;\n        font-variant-numeric: tabular-nums;\n      }\n\n      button {\n        font: inherit;\n        padding: 8px 14px;\n        border-radius: 999px;\n        border: 0;\n        background: #00C65A;\n        color: #fff;\n        font-weight: 700;\n        cursor: pointer;\n      }\n    </style>\n  </head>\n\n  <body>\n\n    <h1>Predict the Cup · leaderboard</h1>\n    <p class=\"sub\">One box, one ranked table.</p>\n\n    <table>\n      <thead>\n        <tr>\n          <th class=\"rank\">#</th>\n          <th>Player</th>\n          <th class=\"total\">Total</th>\n        </tr>\n      </thead>\n      <tbody id=\"board\"></tbody>\n    </table>\n\n    <p style=\"margin-top:14px\">\n      <button id=\"run\">Run saveAndRank()</button>\n    </p>\n\n    <script>\n\n      var KEY = \"proov_predict_v1\";\n\n      var rowsThisRound = [\n        { name: \"You\", total: 17 },\n        { name: \"House bot\", total: 11 },\n        { name: \"Alex\", total: 22 }\n      ];\n\n      function render(rows) {\n        var html = rows.map(function (r, i) {\n          return \"\"\n            + \"<tr>\"\n            + \"<td class='rank'>\" + (i + 1) + \"</td>\"\n            + \"<td>\" + r.name + \"</td>\"\n            + \"<td class='total'>\" + r.total + \"</td>\"\n            + \"</tr>\";\n        }).join(\"\");\n\n        document.getElementById(\"board\").innerHTML = html;\n      }\n\n      function saveAndRank(entries) {\n\n        // Save to localStorage\n        localStorage.setItem(KEY, JSON.stringify(entries));\n\n        // Read back\n        var rows = JSON.parse(localStorage.getItem(KEY));\n\n        // Sort highest score first\n        rows.sort(function(a, b) {\n          return b.total - a.total;\n        });\n\n        // Render leaderboard\n        render(rows);\n      }\n\n      document.getElementById(\"run\").addEventListener(\"click\", function () {\n        saveAndRank(rowsThisRound);\n      });\n\n      window.saveAndRank = saveAndRank;\n      window.__LB_KEY__ = KEY;\n      window.__LB_ROWS__ = rowsThisRound;\n\n    </script>\n\n  </body>\n</html>","ranAt":"2026-07-26T10:11:32.680Z","passed":false,"attempt":1}

Act5 Assemble

My solution
{"code":"<!doctype html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n<title>Predict the Cup — my World Cup prediction game</title>\n<style>\n  :root { --green:#00C65A; --ink:#0E1726; --soft:#3F4B5F; --faint:#6A7589; --line:#E4E8EE; --paper:#fff; --bg:#F4F7F6; }\n  * { box-sizing: border-box; }\n  body { font-family: ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif;\n         margin:0; background:var(--bg); color:var(--ink); }\n  .wrap { max-width: 760px; margin: 0 auto; padding: 22px 18px 40px; }\n  header { display:flex; align-items:center; gap:12px; margin-bottom:6px; }\n  .badge { width:42px; height:42px; border-radius:12px; background:var(--green); color:#fff;\n           display:flex; align-items:center; justify-content:center; font-weight:900; font-size:18px; }\n  h1 { font-size:21px; margin:0; letter-spacing:-0.01em; }\n  .tag { color:var(--faint); font-size:13px; margin:2px 0 18px; }\n  h2 { font-size:13px; text-transform:uppercase; letter-spacing:0.12em; color:var(--faint); margin:24px 0 12px; }\n  #board { display:grid; grid-template-columns:1fr; gap:12px; }\n  @media (min-width:560px){ #board { grid-template-columns:1fr 1fr; } }\n  .match { background:var(--paper); border:1px solid var(--line); border-radius:14px; padding:14px; }\n  .meta { color:var(--faint); font-size:10.5px; text-transform:uppercase; letter-spacing:0.12em; margin-bottom:8px; }\n  .teams { display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:8px; font-weight:800; font-size:15px; }\n  .teams .vs { color:var(--faint); font-weight:700; font-size:11px; }\n  .teams .away { text-align:right; }\n  .picks { display:grid; grid-template-columns:1fr auto 1fr; align-items:center; gap:8px; margin-top:10px; }\n  .picks input { padding:10px; border:1px solid var(--line); border-radius:9px; text-align:center;\n                 font:inherit; font-weight:800; font-size:16px; width:100%; }\n  .picks input:focus { outline:2px solid var(--green); border-color:var(--green); }\n  .picks .dash { color:var(--faint); font-weight:800; text-align:center; }\n  .botline { margin-top:10px; font-size:12px; color:var(--soft); }\n  .botline b { color:var(--ink); font-variant-numeric:tabular-nums; }\n  .botline .prob { color:var(--faint); font-weight:600; }\n  .hint { color:var(--faint); font-size:12px; line-height:1.5; margin:8px 0 2px; max-width:560px; }\n  .challenge-banner { background:rgba(0,198,90,0.10); border:1px solid var(--green); border-radius:12px; padding:12px 14px; font-size:14px; font-weight:700; color:var(--ink); margin:14px 0 4px; }\n  .vs-friend { font-size:15px; font-weight:800; color:var(--green); margin-top:12px; }\n  .share-row { display:flex; gap:8px; flex-wrap:wrap; align-items:center; margin-top:14px; }\n  .namebox { flex:1; min-width:150px; padding:11px 12px; border:1px solid var(--line); border-radius:10px; font:inherit; }\n  .namebox:focus { outline:2px solid var(--green); border-color:var(--green); }\n  .sharebtn { font:inherit; font-weight:800; color:#fff; background:var(--ink); border:0; border-radius:999px; padding:11px 18px; cursor:pointer; }\n  .sharebtn:hover { filter:brightness(1.15); }\n  .shareurl { width:100%; margin-top:8px; padding:9px 11px; border:1px solid var(--line); border-radius:8px; font-family:ui-monospace,Menlo,monospace; font-size:12px; color:var(--soft); }\n  .proov-credit { margin-top:12px; font-size:11.5px; }\n  .proov-credit a { color:var(--green); font-weight:800; text-decoration:none; }\n  .result { margin-top:10px; font-size:12px; font-weight:700; color:var(--green);\n            border-top:1px dashed var(--line); padding-top:9px; }\n  .scorebtn { margin-top:18px; font:inherit; font-weight:800; font-size:15px; color:#fff;\n              background:var(--green); border:0; border-radius:999px; padding:13px 22px; cursor:pointer; width:100%; }\n  @media (min-width:560px){ .scorebtn { width:auto; } }\n  .
…

Final Submission

My solution
{"url":"https://gentle-lebkuchen-ff5f12.netlify.app/","submittedAt":"2026-07-26T10:16:07.976Z"}

Jupyterlite Code

My solution
base64:CiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgTm90ZWJvb2s6IHZ3X3NwcmludDFfZWRhLmlweW5iCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojIDxkaXYgc3R5bGU9ImJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMxQTNDNkUgMCUsICMwQjEzMkIgMTAwJSk7IGJvcmRlci1yYWRpdXM6IDE2cHg7IHBhZGRpbmc6IDM2cHggMzJweDsgbWFyZ2luLWJvdHRvbTogOHB4OyI+CiMgICA8ZGl2IHN0eWxlPSJkaXNwbGF5OmZsZXg7IGFsaWduLWl0ZW1zOmNlbnRlcjsgZ2FwOjE2cHg7IG1hcmdpbi1ib3R0b206MjBweDsiPgojICAgICA8ZGl2PgojICAgICAgIDxkaXYgc3R5bGU9ImNvbG9yOiM2MGE1ZmE7IGZvbnQtc2l6ZToxMXB4OyBmb250LXdlaWdodDo3MDA7IGxldHRlci1zcGFjaW5nOjNweDsgdGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlOyBtYXJnaW4tYm90dG9tOjRweDsiPlByb29WIFdvcmsgRXhwZXJpZW5jZTwvZGl2PgojICAgICAgIDxkaXYgc3R5bGU9ImNvbG9yOiNmZmY7IGZvbnQtc2l6ZToyMnB4OyBmb250LXdlaWdodDo4MDA7IGxpbmUtaGVpZ2h0OjEuMjsiPlVzZWQgQ2FyIFByaWNlIFByZWRpY3Rpb248L2Rpdj4KIyAgICAgPC9kaXY+CiMgICA8L2Rpdj4KIyAgIDxkaXYgc3R5bGU9ImRpc3BsYXk6ZmxleDsgZ2FwOjEwcHg7IGZsZXgtd3JhcDp3cmFwOyBtYXJnaW4tYm90dG9tOjIwcHg7Ij4KIyAgICAgPHNwYW4gc3R5bGU9ImJhY2tncm91bmQ6cmdiYSgyNTUsMjU1LDI1NSwwLjEyKTsgY29sb3I6I2ZmZjsgYm9yZGVyLXJhZGl1czoyMHB4OyBwYWRkaW5nOjVweCAxNHB4OyBmb250LXNpemU6MTJweDsgZm9udC13ZWlnaHQ6NjAwOyI+RGF0YSBTY2llbnRpc3QgLSBWVyBDYXNlIFN0dWR5PC9zcGFuPgojICAgICA8c3BhbiBzdHlsZT0iYmFja2dyb3VuZDpyZ2JhKDI1NSwyNTUsMjU1LDAuMTIpOyBjb2xvcjojZmZmOyBib3JkZXItcmFkaXVzOjIwcHg7IHBhZGRpbmc6NXB4IDE0cHg7IGZvbnQtc2l6ZToxMnB4OyBmb250LXdlaWdodDo2MDA7Ij5QeXRob24gLyBzY2lraXQtbGVhcm4gLyBwYW5kYXM8L3NwYW4+CiMgICAgIDxzcGFuIHN0eWxlPSJiYWNrZ3JvdW5kOnJnYmEoMjU1LDI1NSwyNTUsMC4xMik7IGNvbG9yOiNmZmY7IGJvcmRlci1yYWRpdXM6MjBweDsgcGFkZGluZzo1cHggMTRweDsgZm9udC1zaXplOjEycHg7IGZvbnQtd2VpZ2h0OjYwMDsiPkVzdC4gNC02IGhvdXJzPC9zcGFuPgojICAgPC9kaXY+CiMgICA8ZGl2IHN0eWxlPSJiYWNrZ3JvdW5kOnJnYmEoMjU1LDI1NSwyNTUsMC4wOCk7IGJvcmRlcjoxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjE1KTsgYm9yZGVyLXJhZGl1czoxMHB4OyBwYWRkaW5nOjEycHggMTZweDsiPgojICAgICA8cCBzdHlsZT0iY29sb3I6Izk0YTNiODsgZm9udC1zaXplOjExcHg7IG1hcmdpbjowOyBsaW5lLWhlaWdodDoxLjY7Ij4KIyAgICAgICA8c3Ryb25nIHN0eWxlPSJjb2xvcjojY2JkNWUxOyI+TGVnYWwgbm90aWNlOjwvc3Ryb25nPiBUaGlzIGlzIGFuIGluZGVwZW5kZW50IGVkdWNhdGlvbmFsIGNhc2Ugc3R1ZHkgY3JlYXRlZCBieSBQcm9vVi4gVm9sa3N3YWdlbiwgQXVkaSwgVlcsIEdvbGYsIGFuZCBBNCBhcmUgdHJhZGVtYXJrcyBvZiBWb2xrc3dhZ2VuIEFHLiBUaGlzIG5vdGVib29rIGlzIG5vdCBlbmRvcnNlZCBieSwgYWZmaWxpYXRlZCB3aXRoLCBvciBzcG9uc29yZWQgYnkgVm9sa3N3YWdlbiBBRyBvciBhbnkgb2YgaXRzIHN1YnNpZGlhcmllcy4gRGF0YXNldCBzb3VyY2VkIGZyb20gdGhlIDxlbT4xMDAsMDAwIFVLIFVzZWQgQ2FyPC9lbT4gZGF0YXNldCBieSBhZGl0eWFkZXNhaTEzIG9uIEthZ2dsZSwgdXNlZCB1bmRlciBub21pbmF0aXZlIGZhaXIgdXNlIGZvciBlZHVjYXRpb25hbCBwdXJwb3NlcyBvbmx5LgojICAgICA8L3A+CiMgICA8L2Rpdj4KIyA8L2Rpdj4KCiMgIyMgWW91ciBNaXNzaW9uCiMgCiMgSW4gdGhpcyBzaW11bGF0ZWQgY2FzZSBzdHVkeSBieSBQcm9vViwgeW91IHdpbGwgc3RlcCBpbnRvIHRoZSByb2xlIG9mIGEgRGF0YSBTY2llbnRpc3QgYW5hbHl6aW5nIHRoZSB1c2VkIGNhciBtYXJrZXQgZm9yIFZvbGtzd2FnZW4gYW5kIEF1ZGkgdmVoaWNsZXMuIENlcnRpZmllZCBQcmUtT3duZWQgKENQTykgcHJvZ3JhbXMgcHJpY2UgdGhvdXNhbmRzIG9mIHVzZWQgdmVoaWNsZXMgZXZlcnkgbW9udGggLSBhbmQgb2Z0ZW4gZG8gaXQgbWFudWFsbHkuIFlvdXIgam9iOiAqKmJ1aWxkIGEgbWFjaGluZSBsZWFybmluZyBtb2RlbCB0aGF0IHByZWRpY3RzIHJlc2FsZSBwcmljZXMgYXV0b21hdGljYWxseSoqLgojIAojIFlvdSdsbCB3b3JrIHdpdGggcmVhbCBVSyBtYXJrZXQgZGF0YToKIyAtICoqfjE1LDIwMCBWVyBsaXN0aW5ncyoqIChtb3N0bHkgR29sZikKIyAtICoqfjEwLDcwMCBBdWRpIGxpc3RpbmdzKiogKG1vc3RseSBBNCkKIyAtIENvbHVtbnM6IGBtb2RlbGAsIGB5ZWFyYCwgYHByaWNlYCwgYHRyYW5zbWlzc2lvbmAsIGBtaWxlYWdlYCwgYGZ1ZWxUeXBlYCwgYHRheGAsIGBtcGdgLCBgZW5naW5lU2l6ZWAKIyAKIyBCeSB0aGUgZW5kIHlvdSdsbCBoYXZlIHRyYWluZWQgdHdvIG1vZGVscywgY29tcGFyZWQgdGhlbSwgYW5kIHdyaXR0ZW4gYSBidXNpbmVzcyByZWNvbW1lbmRhdGlvbiBmb3IgbGVhZGVyc2hpcC4KIyAKIyAtLS0KIyAKIyAqKkZvbGxvdyB0aGUgc2VjdGlvbnMgaW4gb3JkZXIuKiogRWFjaCBvbmUgaGFzIGEgY2hlY2tsaXN0LiBGaWxsIGluIHRoZSBgIyBZT1VSIENPREUgSEVSRWAgY2VsbHMuCgojIC0tLQojICMjIFNlY3Rpb24gMCAtIFNldHVwICYgRGF0YSBMb2FkaW5nCiMgPiAqKlJ1biB0aGlzIGNlbGwgZmlyc3QuIERvIG5vdCBtb2RpZnkgaXQuKioKCiMgSW5bM106CiMgUHJvb1Y6IFZXICYgQXVkaSBVc2VkIENhciBQcmljZSBQcmVkaWN0aW9uCiMgVm9sa3N3YWdlbiwgQXVkaSwgVlcsI
…
Verified certificateTamper-proof · issued by ProoV
Certified

Self-directed project

Amazon Robotics - Black-Friday Fleet Coordination

Software Engineering · July 2026

98/ 100

Built an end-to-end Amazon Robotics fleet-coordination solution for Black Friday surge conditions: framed the bottleneck as aisle congestion and dock contention, implemented single-agent A* with an admissible Manhattan heuristic, extended it to centralized cooperative planning with vertex and edge reservations, and validated a realistic operating policy in simulation. The final pitch tied zero-collision execution and sustained throughput to a concrete pilot ask for one FC zone during a named surge event.

Graded against

  • Problem framing & operational stakes20%
  • Algorithmic depth - A* and cooperative coordination30%
  • Coordination policy realism - deadlock, charging, idle25%
  • Throughput trade-off analysis15%
  • Executive pitch to leadership10%

Passed · pass mark 55/100

What stood out6
  • Implemented A* with an admissible Manhattan heuristic on a 4-connected grid and showed it outperforming Dijkstra in node expansions.
  • Built a cooperative reservation table that books both vertices and directed edges, preventing same-cell and head-on swap collisions.
  • Chose a realistic fleet policy: centralized coordination, priority-watchdog deadlock handling, staggered charging, and dispersed perimeter idle parking.
  • Used simulator outputs to identify a concave throughput curve and locked a specific sweet spot fleet size of 36 robots.
  • Leakage-Free Multi-Agent Coordination
  • Honest Simulation-Based Evaluation
The work I submitted12 tasks

Amazon Robotics Context

My solution
{"viewedAt":"2026-07-15T08:13:46.125Z","timeline":["2003","2012","2015","2025"],"driveUnitStats":["110 kg","450 kg","5.5 km / h"],"disclaimerShown":true,"sourcesShown":true,"sources":["Amazon, Kiva Systems acquisition (2012)","About Amazon, one millionth robot (2025)","Published Kiva / Amazon drive-unit specifications","Statista, Amazon net sales by leading market (2024)","Amazon, Bad Hersfeld (FRA1) site","Wurman, D’Andrea & Mountz (2008), AI Magazine"]}

Grid World Theory

My solution
{"concept":"grid-world-model","cellTypes":["free","rack","pick","pack","charge"],"viewedAt":"2026-07-15T08:16:44.273Z"}

State Representation Task Validator

My solution
{"code":"# Auto-validator: every robot needs a position AND a goal.\n# The planner refuses to schedule a robot whose state is incomplete.\nimport json\n\nstate = json.loads(r\"\"\"{\n  \"robots\": [\n    {\n      \"id\": \"R1\",\n      \"x\": 3,\n      \"y\": 3,\n      \"goal\": null,\n      \"battery\": 100\n    },\n    {\n      \"id\": \"R2\",\n      \"x\": 4,\n      \"y\": 3,\n      \"goal\": null,\n      \"battery\": 94\n    },\n    {\n      \"id\": \"R3\",\n      \"x\": 5,\n      \"y\": 3,\n      \"goal\": null,\n      \"battery\": 88\n    },\n    {\n      \"id\": \"R4\",\n      \"x\": 9,\n      \"y\": 3,\n      \"goal\": null,\n      \"battery\": 82\n    },\n    {\n      \"id\": \"R5\",\n      \"x\": 3,\n      \"y\": 9,\n      \"goal\": null,\n      \"battery\": 76\n    }\n  ]\n}\"\"\")\n\ndef validate(state):\n    bots = state.get('robots', [])\n    issues = []\n    for b in bots:\n        if b.get('x') is None or b.get('y') is None:\n            issues.append(f\"robot {b['id']} has no position\")\n        if not b.get('goal') or b['goal'].get('x') is None:\n            issues.append(f\"robot {b['id']} has no goal\")\n    return issues\n\nissues = validate(state)\nif issues:\n    print(\"INCOMPLETE STATE\")\n    for line in issues:\n        print(\" -\", line)\nelse:\n    print(f\"OK, {len(state['robots'])} robots, each with position + goal.\")\n    print('Planner can schedule this state.')\n","stdout":"INCOMPLETE STATE\n - robot R1 has no goal\n - robot R2 has no goal\n - robot R3 has no goal\n - robot R4 has no goal\n - robot R5 has no goal\n","stderr":"","error":null,"imageCount":0,"durationMs":2,"ranAt":"2026-07-15T08:22:11.893Z"}

State Representation Task

My solution
{"robots":[{"id":"R1","x":3,"y":3,"goal":{"x":9,"y":3},"battery":100},{"id":"R2","x":4,"y":3,"goal":{"x":3,"y":9},"battery":94},{"id":"R3","x":5,"y":3,"goal":{"x":9,"y":9},"battery":88},{"id":"R4","x":3,"y":6,"goal":{"x":0,"y":9},"battery":82},{"id":"R5","x":5,"y":6,"goal":{"x":9,"y":0},"battery":76}],"placedAt":"2026-07-15T08:23:11.349Z"}

Phase1 Recap

My solution
{"phase":1,"phaseTitle":"Grid-world modeling","takeaways":[{"id":"grid-of-typed-cells","title":"Warehouse = grid of typed cells"},{"id":"state-positions-goals-batteries","title":"State = positions + goals + batteries"},{"id":"collisions-vertex-and-edge","title":"Collisions = same cell OR same edge at the same tick"}],"skillAxisTicked":"Modeling"}

Astar Theory

My solution
{"heuristic":"manhattan","admissible":true,"viewed_comparison":true,"replays":0,"astar_expanded":32,"dijkstra_expanded":107}

Astar Implementation Cell

My solution
{"code":"# A* path planning for one warehouse drive-unit.\n# Complete the three TODOs and click \"Run cell\" to replay your A* on the\n# 15x15 fixture grid on the right.\n#\n# The grid is a list of rows: 0 = free aisle, 1 = rack obstacle.\n# Robots move 4-connected (up/down/left/right), no diagonals.\n\nimport heapq, json, time\n\nGRID  = __ASTAR_GRID__         # injected by the harness\nSTART = tuple(__ASTAR_START__) # (row, col)\nGOAL  = tuple(__ASTAR_GOAL__)  # (row, col)\nH, W  = len(GRID), len(GRID[0])\n\n\ndef h(cell, goal):\n    # Manhattan distance, admissible AND tight on a 4-connected grid.\n    (r1, c1), (r2, c2) = cell, goal\n    return abs(r1 - r2) + abs(c1 - c2)\n\n\ndef neighbours(cell):\n    r, c = cell\n    # 4-connected moves: up, down, left, right.\n    for dr, dc in [(-1, 0), (1, 0), (0, -1), (0, 1)]:\n        nr, nc = r + dr, c + dc\n        if 0 <= nr < H and 0 <= nc < W and GRID[nr][nc] == 0:\n            yield (nr, nc)\n\n\ndef reconstruct_path(came_from, current):\n    path = [current]\n    while current in came_from:\n        current = came_from[current]\n        path.append(current)\n    return list(reversed(path))\n\n\ndef a_star(start, goal):\n    # open_set holds (f_score, tiebreak, cell) tuples; heapq pops the smallest.\n    counter = 0\n    open_set  = [(0, counter, start)]\n    came_from = {}\n    g_score   = {start: 0}\n    closed    = set()\n    visited_order = []   # cells in the order A* expanded them, the frontier replay\n    expansions = 0\n\n    while open_set:\n        _, _, current = heapq.heappop(open_set)\n        if current in closed:\n            continue\n        closed.add(current)\n        visited_order.append(current)\n        expansions += 1\n\n        if current == goal:\n            return reconstruct_path(came_from, current), visited_order, expansions\n\n        for nb in neighbours(current):\n            if nb in closed:\n                continue\n            tentative_g = g_score[current] + 1\n\n            if tentative_g < g_score.get(nb, float('inf')):\n                came_from[nb] = current\n                g_score[nb]   = tentative_g\n\n                # TODO 1, f-score expression: f = g + h\n                f = tentative_g + h(nb, goal)\n\n                # TODO 2, tie-breaking: prefer cells with smaller h, so when\n                # two cells tie on f the planner doesn't wander. Increment\n                # counter so heapq keeps insertion order as a final tiebreak.\n                counter += 1\n                tiebreak = (h(nb, goal), counter)\n\n                heapq.heappush(open_set, (f, tiebreak, nb))\n\n    return None, visited_order, expansions\n\n\nt0 = time.perf_counter()\npath, visited, expansions = a_star(START, GOAL)\nruntime_ms = (time.perf_counter() - t0) * 1000.0\n\n# TODO 3, neighbour expansion sanity check.\n# The neighbours() helper above already lists the 4-connected moves, but\n# the planner should NEVER expand into a cell with GRID[r][c] == 1.\n# If you change neighbours(), make sure it still filters obstacles.\n_ = list(neighbours(START))  # not graded; just here so the student edits\n\n# Emit a single line of JSON the right-side visualiser parses to animate.\nprint(\"__ASTAR_RESULT__\" + json.dumps({\n    \"path\":            path,\n    \"visited\":         visited,\n    \"nodes_expanded\":  expansions,\n    \"path_length\":     0 if path is None else len(path),\n    \"runtime_ms\":      round(runtime_ms, 2),\n}))\n","passed":true,"reason":"Path is optimal and obstacle-free.","path_length":29,"nodes_expanded":31,"runtime_ms":0.44,"optimal_length":29,"attempt_count":1,"used_canonical":false,"ranAt":"2026-07-15T08:30:24.779Z"}

Astar Solution Correct

My solution
true

Single Unit Challenge

My solution
{"passed":true,"usedFallback":false,"usedHint":false,"runs":[{"maze":"Maze 1 · Open aisles","passed":true,"path_length":49,"optimal_length":49,"nodes_expanded":64,"runtime_ms":0.28},{"maze":"Maze 2 · Narrow corridors","passed":true,"path_length":49,"optimal_length":49,"nodes_expanded":61,"runtime_ms":0.25},{"maze":"Maze 3 · Dense racks","passed":true,"path_length":49,"optimal_length":49,"nodes_expanded":75,"runtime_ms":0.32}],"ranAt":"2026-07-15T08:31:48.065Z"}

Phase2 Recap

My solution
{"phase":2,"phaseTitle":"Single-agent A* search","takeaways":[{"id":"astar-equals-dijkstra-plus-admissible-heuristic","title":"A* = Dijkstra + admissible heuristic"},{"id":"manhattan-on-four-connected-grid","title":"Manhattan distance on 4-connected grids"},{"id":"optimal-and-faster-than-dijkstra","title":"Optimal AND faster than Dijkstra"}],"skillAxisTicked":"A* search"}

Multi Agent Problem

My solution
{"viewed":true,"scenario":"three-robots-one-corridor","didSeeConflict":true,"didSeeReservationResolution":true}

Reservation Table Theory

My solution
{"concept":"reservation-table-time-axis","keyShape":"(x, y, t) → robot_id","acknowledgedWaitIsLegal":true,"acknowledgedEdgeReservations":true,"viewed_3d_diagram":false,"replays":1}
Verified certificateTamper-proof · issued by ProoV
Certified

Self-directed project

Machine Learning for Automotive

AI / ML · June 2026

84/ 100

A verified, self-directed industry project — completed and passed a real industry rubric at 84/100 on ProoV.

Graded against

  • Exploratory Data Analysis20%
  • Feature Engineering25%
  • Model Building & Evaluation35%
  • Business Communication20%

Passed · pass mark 60/100

What stood out6
  • Correctly compared Linear Regression and Random Forest using R², MAE, and RMSE
  • Identified vehicle age, mileage, and engine size as the top pricing drivers
  • Translated model performance into a clear CPO business recommendation
  • Included a quantified financial impact statement to support decision-making
  • Exploratory Data Analysis
  • Feature Engineering
The work I submitted5 tasks

VW Sprint1 Complete

My solution
{"completed":true,"notebookName":"vw_sprint1_eda.ipynb"}

VW Sprint2 Complete

My solution
{"completed":true,"notebookName":"vw_sprint2_features.ipynb"}

VW Sprint3 Complete

My solution
{"completed":true,"notebookName":"vw_sprint3_models.ipynb"}

VW Business Insights

My solution
{"text":"Our analysis found that the Random Forest model clearly outperformed Linear Regression for used car price prediction. Linear Regression achieved an R² score of 0.8328 with an MAE of £2,622 and an RMSE of £4,070. The Random Forest model improved performance to an R² of 0.9504, reduced MAE to £1,438, and lowered RMSE to £2,218. This represents a 45% reduction in average pricing error and explains 95% of the variation in vehicle prices.\n\nThe three most important pricing factors identified by the Random Forest model were vehicle age, mileage, and engine size. Vehicle age was the strongest predictor because depreciation has the largest impact on resale value. Mileage reflects vehicle usage and wear, while engine size is associated with vehicle specification and market value.\n\nThe financial impact is significant. If 30% of 150,000 annual trade-ins are mispriced by £2,000 each, the total portfolio mispricing risk is £90 million per year (45,000 vehicles × £2,000). Reducing pricing errors through machine learning could protect a substantial portion of this value.\n\nI recommend deploying the Random Forest model as the primary pricing tool for Certified Pre-Owned operations. Its higher accuracy will improve trade-in valuations, reduce pricing inconsistencies, and support more profitable inventory and residual value decisions across the portfolio.","charCount":1358,"selfChecks":[{"label":"Model comparison","checked":false},{"label":"Top features identified","checked":false},{"label":"Financial Impact","checked":false},{"label":"Clear recommendation","checked":false}]}

Jupyterlite Code

My solution
base64:CiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMgTm90ZWJvb2s6IHZ3X3NwcmludDFfZWRhLmlweW5iCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgojIDxkaXYgc3R5bGU9ImJhY2tncm91bmQ6IGxpbmVhci1ncmFkaWVudCgxMzVkZWcsICMxQTNDNkUgMCUsICMwQjEzMkIgMTAwJSk7IGJvcmRlci1yYWRpdXM6IDE2cHg7IHBhZGRpbmc6IDM2cHggMzJweDsgbWFyZ2luLWJvdHRvbTogOHB4OyI+CiMgICA8ZGl2IHN0eWxlPSJkaXNwbGF5OmZsZXg7IGFsaWduLWl0ZW1zOmNlbnRlcjsgZ2FwOjE2cHg7IG1hcmdpbi1ib3R0b206MjBweDsiPgojICAgICA8ZGl2PgojICAgICAgIDxkaXYgc3R5bGU9ImNvbG9yOiM2MGE1ZmE7IGZvbnQtc2l6ZToxMXB4OyBmb250LXdlaWdodDo3MDA7IGxldHRlci1zcGFjaW5nOjNweDsgdGV4dC10cmFuc2Zvcm06dXBwZXJjYXNlOyBtYXJnaW4tYm90dG9tOjRweDsiPlByb29WIFdvcmsgRXhwZXJpZW5jZTwvZGl2PgojICAgICAgIDxkaXYgc3R5bGU9ImNvbG9yOiNmZmY7IGZvbnQtc2l6ZToyMnB4OyBmb250LXdlaWdodDo4MDA7IGxpbmUtaGVpZ2h0OjEuMjsiPlVzZWQgQ2FyIFByaWNlIFByZWRpY3Rpb248L2Rpdj4KIyAgICAgPC9kaXY+CiMgICA8L2Rpdj4KIyAgIDxkaXYgc3R5bGU9ImRpc3BsYXk6ZmxleDsgZ2FwOjEwcHg7IGZsZXgtd3JhcDp3cmFwOyBtYXJnaW4tYm90dG9tOjIwcHg7Ij4KIyAgICAgPHNwYW4gc3R5bGU9ImJhY2tncm91bmQ6cmdiYSgyNTUsMjU1LDI1NSwwLjEyKTsgY29sb3I6I2ZmZjsgYm9yZGVyLXJhZGl1czoyMHB4OyBwYWRkaW5nOjVweCAxNHB4OyBmb250LXNpemU6MTJweDsgZm9udC13ZWlnaHQ6NjAwOyI+RGF0YSBTY2llbnRpc3QgLSBWVyBDYXNlIFN0dWR5PC9zcGFuPgojICAgICA8c3BhbiBzdHlsZT0iYmFja2dyb3VuZDpyZ2JhKDI1NSwyNTUsMjU1LDAuMTIpOyBjb2xvcjojZmZmOyBib3JkZXItcmFkaXVzOjIwcHg7IHBhZGRpbmc6NXB4IDE0cHg7IGZvbnQtc2l6ZToxMnB4OyBmb250LXdlaWdodDo2MDA7Ij5QeXRob24gLyBzY2lraXQtbGVhcm4gLyBwYW5kYXM8L3NwYW4+CiMgICAgIDxzcGFuIHN0eWxlPSJiYWNrZ3JvdW5kOnJnYmEoMjU1LDI1NSwyNTUsMC4xMik7IGNvbG9yOiNmZmY7IGJvcmRlci1yYWRpdXM6MjBweDsgcGFkZGluZzo1cHggMTRweDsgZm9udC1zaXplOjEycHg7IGZvbnQtd2VpZ2h0OjYwMDsiPkVzdC4gNC02IGhvdXJzPC9zcGFuPgojICAgPC9kaXY+CiMgICA8ZGl2IHN0eWxlPSJiYWNrZ3JvdW5kOnJnYmEoMjU1LDI1NSwyNTUsMC4wOCk7IGJvcmRlcjoxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjE1KTsgYm9yZGVyLXJhZGl1czoxMHB4OyBwYWRkaW5nOjEycHggMTZweDsiPgojICAgICA8cCBzdHlsZT0iY29sb3I6Izk0YTNiODsgZm9udC1zaXplOjExcHg7IG1hcmdpbjowOyBsaW5lLWhlaWdodDoxLjY7Ij4KIyAgICAgICA8c3Ryb25nIHN0eWxlPSJjb2xvcjojY2JkNWUxOyI+TGVnYWwgbm90aWNlOjwvc3Ryb25nPiBUaGlzIGlzIGFuIGluZGVwZW5kZW50IGVkdWNhdGlvbmFsIGNhc2Ugc3R1ZHkgY3JlYXRlZCBieSBQcm9vVi4gVm9sa3N3YWdlbiwgQXVkaSwgVlcsIEdvbGYsIGFuZCBBNCBhcmUgdHJhZGVtYXJrcyBvZiBWb2xrc3dhZ2VuIEFHLiBUaGlzIG5vdGVib29rIGlzIG5vdCBlbmRvcnNlZCBieSwgYWZmaWxpYXRlZCB3aXRoLCBvciBzcG9uc29yZWQgYnkgVm9sa3N3YWdlbiBBRyBvciBhbnkgb2YgaXRzIHN1YnNpZGlhcmllcy4gRGF0YXNldCBzb3VyY2VkIGZyb20gdGhlIDxlbT4xMDAsMDAwIFVLIFVzZWQgQ2FyPC9lbT4gZGF0YXNldCBieSBhZGl0eWFkZXNhaTEzIG9uIEthZ2dsZSwgdXNlZCB1bmRlciBub21pbmF0aXZlIGZhaXIgdXNlIGZvciBlZHVjYXRpb25hbCBwdXJwb3NlcyBvbmx5LgojICAgICA8L3A+CiMgICA8L2Rpdj4KIyA8L2Rpdj4KCiMgIyMgWW91ciBNaXNzaW9uCiMgCiMgSW4gdGhpcyBzaW11bGF0ZWQgY2FzZSBzdHVkeSBieSBQcm9vViwgeW91IHdpbGwgc3RlcCBpbnRvIHRoZSByb2xlIG9mIGEgRGF0YSBTY2llbnRpc3QgYW5hbHl6aW5nIHRoZSB1c2VkIGNhciBtYXJrZXQgZm9yIFZvbGtzd2FnZW4gYW5kIEF1ZGkgdmVoaWNsZXMuIENlcnRpZmllZCBQcmUtT3duZWQgKENQTykgcHJvZ3JhbXMgcHJpY2UgdGhvdXNhbmRzIG9mIHVzZWQgdmVoaWNsZXMgZXZlcnkgbW9udGggLSBhbmQgb2Z0ZW4gZG8gaXQgbWFudWFsbHkuIFlvdXIgam9iOiAqKmJ1aWxkIGEgbWFjaGluZSBsZWFybmluZyBtb2RlbCB0aGF0IHByZWRpY3RzIHJlc2FsZSBwcmljZXMgYXV0b21hdGljYWxseSoqLgojIAojIFlvdSdsbCB3b3JrIHdpdGggcmVhbCBVSyBtYXJrZXQgZGF0YToKIyAtICoqfjE1LDIwMCBWVyBsaXN0aW5ncyoqIChtb3N0bHkgR29sZikKIyAtICoqfjEwLDcwMCBBdWRpIGxpc3RpbmdzKiogKG1vc3RseSBBNCkKIyAtIENvbHVtbnM6IGBtb2RlbGAsIGB5ZWFyYCwgYHByaWNlYCwgYHRyYW5zbWlzc2lvbmAsIGBtaWxlYWdlYCwgYGZ1ZWxUeXBlYCwgYHRheGAsIGBtcGdgLCBgZW5naW5lU2l6ZWAKIyAKIyBCeSB0aGUgZW5kIHlvdSdsbCBoYXZlIHRyYWluZWQgdHdvIG1vZGVscywgY29tcGFyZWQgdGhlbSwgYW5kIHdyaXR0ZW4gYSBidXNpbmVzcyByZWNvbW1lbmRhdGlvbiBmb3IgbGVhZGVyc2hpcC4KIyAKIyAtLS0KIyAKIyAqKkZvbGxvdyB0aGUgc2VjdGlvbnMgaW4gb3JkZXIuKiogRWFjaCBvbmUgaGFzIGEgY2hlY2tsaXN0LiBGaWxsIGluIHRoZSBgIyBZT1VSIENPREUgSEVSRWAgY2VsbHMuCgojIC0tLQojICMjIFNlY3Rpb24gMCAtIFNldHVwICYgRGF0YSBMb2FkaW5nCiMgPiAqKlJ1biB0aGlzIGNlbGwgZmlyc3QuIERvIG5vdCBtb2RpZnkgaXQuKioKCiMgSW5bM106CiMgUHJvb1Y6IFZXICYgQXVkaSBVc2VkIENhciBQcmljZSBQcmVkaWN0aW9uCiMgVm9sa3N3YWdlbiwgQXVkaSwgVlcsI
…
Verified certificateTamper-proof · issued by ProoV
3Projects completed
3Verified certificates
89Average score
Create your portfolio with ProoV