Rotary, PWC deliver clean-energy kitchen

Incoming Rotary Club of Dar es Salaam Sunset president Susan Nelima (left) and outgoing president Tahir Othman (fourth left) pose with representatives from PwC, teachers and pupils of Charambe Primary School after the handover of a newly constructed gas-powered kitchen. PHOTO | COURTESY

Dar es Salaam. More than 3,000 pupils at Charambe Primary School will benefit from improved school meals and a healthier learning environment following the handover of a gas-powered kitchen by the Rotary Club of Dar es Salaam Sunset in partnership with PwC under the Jiko Safi Clean Energy Project.

The facility replaces the school’s traditional firewood cooking system, reducing exposure to smoke for pupils and kitchen staff while cutting reliance on firewood.

Rotary Club of Dar es Salaam Sunset President, Mr Tahir Othman, said the project reflects the club’s focus on practical community interventions.

“This project is about investing in children’s health, improving their learning environment and working with partners to deliver lasting impact,” he said.

The project also included the donation of cooking equipment, including gas cylinders and modern pots, renovation of student toilets, provision of 100 new desks, repair of 78 others, sports jerseys for pupils, and tree-planting activities around the school.

Charambe Primary School has grown from 2,030 pupils in 2004 to 3,233 pupils, with 48 teachers. The number of desks has increased from 458 to 636.

School representative Elizabeth Mganga said the improvements have eased meal provision, reduced smoke exposure and improved hygiene and classroom conditions.

Temeke Municipal Director Jomari Satura commended the initiative, saying such partnerships help improve learning environments and support sustainable development, and urged more stakeholders to invest in education infrastructure.

* * If no #mcl-market-ticker element exists, the widget inserts itself right * after this var sel = thisScript && thisScript.getAttribute("data-target"); if (sel) { var t = document.querySelector(sel); if (t) return t; } // 2) A dedicated mount element the host page provides. var el = document.getElementById(CONFIG.targetId); if (el) return el; // 3) Fallback: insert right after this script tag. el = document.createElement("div"); el.id = CONFIG.targetId; if (thisScript && thisScript.parentNode) { thisScript.parentNode.insertBefore(el, thisScript.nextSibling); } else { document.body.appendChild(el); } return el; } // ---- Data pipeline (identical logic to the standalone banner) ------------ function apiUrl(path) { if (!path) return path; if (/^https?:\/\//i.test(path)) return path; return CONFIG.apiBase + (path.charAt(0) === "/" ? "" : "/") + path; } function toNum(v) { var n = parseFloat(String(v == null ? "" : v).replace(/,/g, "")); return isFinite(n) ? n : null; } function fmtNum(v) { var n = parseFloat(String(v).replace(/,/g, "")); if (!isFinite(n)) return String(v == null ? "" : v); var d = Math.abs(n) >= 1 ? 2 : 4; return n.toLocaleString("en-US", { minimumFractionDigits: d, maximumFractionDigits: d }); } function changeClass(d) { if (d == null || Math.abs(d) < 1e-9) return "flat"; return d > 0 ? "up" : "down"; } function arrow(d) { if (d == null || Math.abs(d) < 1e-9) return "▬"; return d > 0 ? "▲" : "▼"; } async function fetchFiles(category, count) { var res = await fetch(apiUrl("/api/files?category=" + category)); if (!res.ok) throw new Error("list " + category + " " + res.status); var list = await res.json(); return Array.isArray(list) ? list.slice(0, count || 1) : []; } async function parseSheet(meta) { var res = await fetch(apiUrl(meta.url)); if (!res.ok) throw new Error("download " + res.status); var buf = await res.arrayBuffer(); var wb = XLSX.read(buf, { type: "array" }); return XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]], { defval: "" }); } function buildStocks(rows) { var items = []; rows.forEach(function (r) { var sym = r["Symbol"] || r["symbol"]; if (!sym) return; var close = toNum(r["Close"]); if (close == null) return; var prev = toNum(r["Prev Close"] || r["Previous Close"]); var delta = prev != null ? close - prev : null; var pct = (delta != null && prev) ? (delta / prev) * 100 : null; items.push({ sym: sym, val: fmtNum(close), delta: delta, pct: pct }); }); return items; } function buildForex(rows, prevRows) { var pmean = {}; (prevRows || []).forEach(function (r) { if (r["Currency"]) pmean[r["Currency"]] = toNum(r["Mean"]); }); var items = []; rows.forEach(function (r) { var cur = r["Currency"]; if (!cur) return; var mean = toNum(r["Mean"]), buy = toNum(r["Buying"]), sell = toNum(r["Selling"]); if (buy == null && sell == null && mean == null) return; var pv = pmean[cur]; var ref = mean != null ? mean : (buy != null && sell != null ? (buy + sell) / 2 : (buy != null ? buy : sell)); var delta = pv != null ? ref - pv : null; var pct = (delta != null && pv) ? (delta / pv) * 100 : null; items.push({ sym: cur, buy: buy != null ? fmtNum(buy) : "—", sell: sell != null ? fmtNum(sell) : "—", delta: delta, pct: pct }); }); var order = CONFIG.majorCurrencies; items.sort(function (a, b) { var ia = order.indexOf(a.sym), ib = order.indexOf(b.sym); if (ia === -1) ia = 999; if (ib === -1) ib = 999; if (ia !== ib) return ia - ib; return a.sym < b.sym ? -1 : 1; }); return items; } function chgHTML(it) { var cls = changeClass(it.delta); if (it.delta == null) return ''; var pctTxt = it.pct != null ? (it.pct >= 0 ? "+" : "") + it.pct.toFixed(2) + "%" : ""; return '' + arrow(it.delta) + " " + pctTxt + ""; } function stockHTML(it) { return '' + it.sym + '' + it.val + "" + chgHTML(it) + ""; } function forexHTML(it) { return '' + it.sym + "" + '' + CONFIG.labels.buy + ' ' + it.buy + ' · ' + CONFIG.labels.sell + ' ' + it.sell + "" + chgHTML(it) + ""; } function pill(t, k) { return '' + t + ""; } function render(track, stocks, forex, dateLabel) { if ((!stocks || !stocks.length) && (!forex || !forex.length)) { track.innerHTML = '
' + CONFIG.labels.unavailable + "
"; track.style.animation = "none"; return; } var parts = []; if (stocks && stocks.length) { parts.push(pill(CONFIG.labels.stocks)); stocks.forEach(function (s) { parts.push(stockHTML(s)); }); } if (forex && forex.length) { parts.push(pill(CONFIG.labels.forex, "forex")); forex.forEach(function (f) { parts.push(forexHTML(f)); }); } if (dateLabel) parts.push('' + CONFIG.labels.updated + ": " + dateLabel + ""); var content = parts.join(""); track.innerHTML = content + content; // duplicated for a seamless loop requestAnimationFrame(function () { var dur = Math.max(20, Math.round((track.scrollWidth / 2) / CONFIG.pxPerSecond)); track.style.animation = "none"; void track.offsetWidth; track.style.animation = "mcl-scroll " + dur + "s linear infinite"; }); } async function load(track) { try { var results = await Promise.allSettled([fetchFiles("hisa", 1), fetchFiles("fedha", 2)]); var stocks = [], forex = [], dateLabel = ""; if (results[0].status === "fulfilled" && results[0].value.length) { var hf = results[0].value[0]; dateLabel = hf.date || ""; stocks = buildStocks(await parseSheet(hf)); } if (results[1].status === "fulfilled" && results[1].value.length) { var ff = results[1].value; var curRows = await parseSheet(ff[0]); var prevRows = ff[1] ? await parseSheet(ff[1]) : []; forex = buildForex(curRows, prevRows); if (!dateLabel) dateLabel = ff[0].date || ""; } render(track, stocks, forex, dateLabel); } catch (e) { if (!track.querySelector(".mcl-item")) { track.innerHTML = '
' + CONFIG.labels.unavailable + "
"; track.style.animation = "none"; } } } function mountAndRun() { injectStyle(); var mount = getMount(); mount.innerHTML = '
' + '
' + CONFIG.brand + "" + '' + CONFIG.live + "
" + '
' + CONFIG.labels.unavailable + "
"; var track = mount.querySelector(".mcl-track"); function go() { load(track); setInterval(function () { load(track); }, CONFIG.refreshMs); } if (window.XLSX) { go(); return; } var sc = document.createElement("script"); sc.src = "https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"; sc.onload = go; sc.onerror = function () { track.innerHTML = '
' + CONFIG.labels.unavailable + "
"; }; (document.head || document.documentElement).appendChild(sc); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", mountAndRun); } else { mountAndRun(); } })();