← back to econlabppe-cloud__econlabppe

Function bodies 29 total

All specs Real LLM only Function bodies
apply_ux function · python · L70-L109 (40 LOC)
apply_elearning_ux.py
def apply_ux():
    # 1. Create the custom SCSS file
    with open("custom_elearning.scss", "w", encoding="utf-8") as f:
        f.write(scss_content)
    print("Created custom_elearning.scss")
    # 2. Update _quarto.yml
    if os.path.exists("_quarto.yml"):
        with open("_quarto.yml", "r", encoding="utf-8") as f:
            lines = f.readlines()

        new_lines = []
        in_html_section = False
        css_added = False
        nav_added = False

        for line in lines:
            new_lines.append(line)
            if line.strip() == "html:":
                in_html_section = True

            if in_html_section:
                # Add CSS reference if not exists
                if line.strip().startswith("theme:") and not css_added:
                    new_lines.append("    css: custom_elearning.scss\n")
                    css_added = True

                # Add page-navigation if not exists
                if line.strip().startswith("toc:") and not nav_added:
      
getProgress function · javascript · L41-L46 (6 LOC)
custom.js
  function getProgress() {
    try {
      const raw = localStorage.getItem(STORAGE_KEY);
      return raw ? JSON.parse(raw) : {};
    } catch (_) { return {}; }
  }
markWeekDone function · javascript · L48-L56 (9 LOC)
custom.js
  function markWeekDone(weekId) {
    try {
      const p = getProgress();
      if (!p[weekId]) {
        p[weekId] = { done: true, ts: Date.now() };
        localStorage.setItem(STORAGE_KEY, JSON.stringify(p));
      }
    } catch (_) {}
  }
getCompletedCount function · javascript · L58-L60 (3 LOC)
custom.js
  function getCompletedCount() {
    return Object.keys(getProgress()).length;
  }
isWeekDone function · javascript · L62-L64 (3 LOC)
custom.js
  function isWeekDone(weekId) {
    return !!getProgress()[weekId];
  }
detectWeekId function · javascript · L67-L75 (9 LOC)
custom.js
  function detectWeekId() {
    const path = window.location.pathname;
    for (const [folder, id] of Object.entries(WEEK_MAP)) {
      if (path.includes(folder)) return id;
    }
    // Fallback: match Week_NN pattern
    const m = path.match(/Week_(\d{2})/);
    return m ? `week_${m[1]}` : null;
  }
loadConfetti function · javascript · L78-L87 (10 LOC)
custom.js
  function loadConfetti() {
    return new Promise((resolve) => {
      if (window.confetti) { resolve(window.confetti); return; }
      const s = document.createElement('script');
      s.src = CONFETTI_CDN;
      s.onload = () => resolve(window.confetti);
      s.onerror = () => resolve(null);         // graceful degradation
      document.head.appendChild(s);
    });
  }
Repobility (the analyzer behind this table) · https://repobility.com
fireCelebration function · javascript · L90-L117 (28 LOC)
custom.js
  async function fireCelebration() {
    const confetti = await loadConfetti();
    if (!confetti) return;

    const defaults = { zIndex: 9999, disableForReducedMotion: true };

    function burst(ratio, opts) {
      confetti(Object.assign({}, defaults, opts, {
        particleCount: Math.floor(200 * ratio),
      }));
    }

    burst(0.25, { spread: 26, startVelocity: 55, origin: { y: 0.6 } });
    burst(0.20, { spread: 60,  origin: { y: 0.65 } });
    burst(0.35, { spread: 100, decay: 0.91, scalar: 0.8, origin: { y: 0.7 } });
    burst(0.10, { spread: 120, startVelocity: 25, decay: 0.92, scalar: 1.2, origin: { y: 0.75 } });
    burst(0.10, { spread: 120, startVelocity: 45, origin: { y: 0.6 } });

    // Bonus side bursts
    setTimeout(() => {
      confetti(Object.assign({}, defaults, {
        particleCount: 60, angle: 60, spread: 55, origin: { x: 0, y: 0.65 }
      }));
      confetti(Object.assign({}, defaults, {
        particleCount: 60, angle: 120, spread: 55, origin: { x: 
burst function · javascript · L96-L100 (5 LOC)
custom.js
    function burst(ratio, opts) {
      confetti(Object.assign({}, defaults, opts, {
        particleCount: Math.floor(200 * ratio),
      }));
    }
buildProgressBar function · javascript · L120-L139 (20 LOC)
custom.js
  function buildProgressBar(compact = false) {
    const done = getCompletedCount();
    const pct  = Math.round((done / TOTAL_WEEKS) * 100);
    const stars = done >= 22 ? ' 🌟' : done >= 15 ? ' ⭐' : done >= 7 ? ' 🔥' : '';

    return `
      <div id="econlab-progress-container">
        <div id="econlab-progress-header">
          <span id="econlab-progress-label">📊 ההתקדמות שלך${stars}</span>
          <span id="econlab-progress-text">${done}/${TOTAL_WEEKS} שבועות</span>
        </div>
        <div id="econlab-progress-bar-bg">
          <div id="econlab-progress-bar" style="width:${pct}%"></div>
        </div>
        <div id="econlab-progress-footer">
          <span>${pct === 0 ? 'בואו נתחיל! 💪' : pct === 100 ? '🎉 השלמת את הקורס!' : `${pct}% הושלם`}</span>
          <span style="opacity:0.75;font-size:0.7rem">מתאפס עם ניקוי Cache</span>
        </div>
      </div>`;
  }
injectProgressBar function · javascript · L142-L169 (28 LOC)
custom.js
  function injectProgressBar() {
    // Don't double-inject
    if (document.getElementById('econlab-progress-container')) return;

    const html = buildProgressBar();
    const wrap = document.createElement('div');
    wrap.innerHTML = html;

    // Try sidebar first, then fallback positions
    const targets = [
      '#quarto-sidebar .sidebar-menu-container',
      '#quarto-sidebar',
      '.sidebar-nav',
      '.sidebar',
    ];

    for (const sel of targets) {
      const el = document.querySelector(sel);
      if (el) {
        el.insertBefore(wrap.firstElementChild, el.firstChild);
        return;
      }
    }

    // Last resort: top of page
    const main = document.querySelector('#quarto-content') || document.querySelector('main');
    if (main) main.insertBefore(wrap.firstElementChild, main.firstChild);
  }
injectGlobalProgressBar function · javascript · L172-L176 (5 LOC)
custom.js
  function injectGlobalProgressBar() {
    const wrapper = document.getElementById('econlab-global-progress-wrapper');
    if (!wrapper) return;
    wrapper.innerHTML = buildProgressBar();
  }
refreshProgressUI function · javascript · L179-L195 (17 LOC)
custom.js
  function refreshProgressUI() {
    const done = getCompletedCount();
    const pct  = Math.round((done / TOTAL_WEEKS) * 100);

    const bar   = document.getElementById('econlab-progress-bar');
    const text  = document.getElementById('econlab-progress-text');
    const foot  = document.querySelector('#econlab-progress-footer span:first-child');
    const label = document.getElementById('econlab-progress-label');

    if (bar)   bar.style.width = pct + '%';
    if (text)  text.textContent = `${done}/${TOTAL_WEEKS} שבועות`;
    if (foot)  foot.textContent = pct === 100 ? '🎉 השלמת את הקורס!' : `${pct}% הושלם`;
    if (label) {
      const stars = done >= 22 ? ' 🌟' : done >= 15 ? ' ⭐' : done >= 7 ? ' 🔥' : '';
      label.textContent = `📊 ההתקדמות שלך${stars}`;
    }
  }
buildFinishButton function · javascript · L198-L215 (18 LOC)
custom.js
  function buildFinishButton(weekId) {
    const done = isWeekDone(weekId);
    return `
      <div id="econlab-finish-container">
        <hr style="margin-bottom:1.5rem;opacity:0.15;">
        ${done ? `
          <button id="econlab-finish-btn" class="completed" disabled>
            ✅ שבוע זה הושלם!
          </button>
          <p class="econlab-completed-msg">כל הכבוד! המשיכו לשבוע הבא 🚀</p>
        ` : `
          <button id="econlab-finish-btn" onclick="window.__econlab.finishWeek()">
            ✅ סיימתי את השבוע!
          </button>
          <p class="econlab-finish-desc">לחצו לאחר השלמת כל המשימות — תקבלו ציון ו-XP!</p>
        `}
      </div>`;
  }
injectFinishButton function · javascript · L218-L242 (25 LOC)
custom.js
  function injectFinishButton() {
    if (document.getElementById('econlab-finish-container')) return;

    const weekId = detectWeekId();
    if (!weekId) return;

    const html = buildFinishButton(weekId);
    const wrap = document.createElement('div');
    wrap.innerHTML = html;

    const targets = [
      '.page-navigation',
      '#quarto-content',
      'main .container-fluid',
      'main',
    ];

    for (const sel of targets) {
      const el = document.querySelector(sel);
      if (el) {
        el.parentNode.insertBefore(wrap.firstElementChild, el);
        return;
      }
    }
  }
Want fix-PRs on findings? Install Repobility's GitHub App · github.com/apps/repobility-bot
handleFinishWeek function · javascript · L245-L275 (31 LOC)
custom.js
  async function handleFinishWeek() {
    const weekId = detectWeekId();
    if (!weekId || isWeekDone(weekId)) return;

    markWeekDone(weekId);

    // Update button immediately
    const btn       = document.getElementById('econlab-finish-btn');
    const container = document.getElementById('econlab-finish-container');

    if (btn) {
      btn.disabled    = true;
      btn.textContent = '✅ שבוע זה הושלם!';
      btn.classList.add('completed');
    }

    if (container) {
      const desc = container.querySelector('.econlab-finish-desc');
      if (desc) desc.remove();

      if (!container.querySelector('.econlab-completed-msg')) {
        const msg = document.createElement('p');
        msg.className   = 'econlab-completed-msg';
        msg.textContent = 'כל הכבוד! המשיכו לשבוע הבא 🚀';
        container.appendChild(msg);
      }
    }

    refreshProgressUI();
    await fireCelebration();
  }
enhanceCodeCopyButtons function · javascript · L278-L292 (15 LOC)
custom.js
  function enhanceCodeCopyButtons() {
    // Quarto renders copy buttons; we add a tooltip/title override
    document.querySelectorAll('.code-copy-button').forEach((btn) => {
      if (!btn.dataset.econlabPatched) {
        btn.title = 'העתק קוד';
        btn.dataset.econlabPatched = 'true';

        btn.addEventListener('click', () => {
          const original = btn.innerHTML;
          btn.innerHTML = '✓ הועתק!';
          setTimeout(() => { btn.innerHTML = original; }, 2000);
        });
      }
    });
  }
highlightActiveSidebarItem function · javascript · L295-L301 (7 LOC)
custom.js
  function highlightActiveSidebarItem() {
    const active = document.querySelector('.sidebar-item.active a, .active.nav-link');
    if (active) {
      active.style.fontWeight = '700';
      active.scrollIntoView({ block: 'nearest', behavior: 'smooth' });
    }
  }
animateProgressBarEntrance function · javascript · L304-L314 (11 LOC)
custom.js
  function animateProgressBarEntrance() {
    const bar = document.getElementById('econlab-progress-bar');
    if (!bar) return;
    const targetWidth = bar.style.width;
    bar.style.width = '0%';
    requestAnimationFrame(() => {
      requestAnimationFrame(() => {
        bar.style.width = targetWidth;
      });
    });
  }
isAssignmentPage function · javascript · L317-L321 (5 LOC)
custom.js
  function isAssignmentPage() {
    const path = window.location.pathname;
    return Object.keys(WEEK_MAP).some((folder) => path.includes(folder)) ||
           /Week_\d{2}/.test(path);
  }
init function · javascript · L324-L339 (16 LOC)
custom.js
  function init() {
    injectProgressBar();
    injectGlobalProgressBar();
    animateProgressBarEntrance();

    if (isAssignmentPage()) {
      injectFinishButton();
    }

    enhanceCodeCopyButtons();
    highlightActiveSidebarItem();

    // Re-patch copy buttons if code blocks load lazily
    const obs = new MutationObserver(() => enhanceCodeCopyButtons());
    obs.observe(document.body, { childList: true, subtree: true });
  }
fix_file function · python · L4-L31 (28 LOC)
fix_hr.py
def fix_file(filepath):
    with open(filepath, 'r', encoding='utf-8') as f:
        lines = f.readlines()

    new_lines = []
    changed = 0
    i = 0
    while i < len(lines):
        line = lines[i]
        if line.rstrip() == '---':
            # Check if it's a Setext heading (previous non-empty line exists)
            prev = lines[i-1].rstrip() if i > 0 else ''
            if prev != '':
                # This is a Setext h2 heading underline — keep it
                new_lines.append(line)
            else:
                # Plain horizontal rule — replace with *** to avoid YAML confusion
                new_lines.append('***\n')
                changed += 1
        else:
            new_lines.append(line)
        i += 1

    if changed:
        with open(filepath, 'w', encoding='utf-8') as f:
            f.writelines(new_lines)
        print(f"Fixed {changed} occurrences in {filepath}")
    return changed
inject_videos function · python · L65-L105 (41 LOC)
inject_validated_videos.py
def inject_videos():
    base_dir = "Assignments"
    for root, dirs, files in os.walk(base_dir):
        for file in files:
            if file.endswith("README.md") or file.endswith(".qmd"):
                file_path = os.path.join(root, file)
                folder_name = os.path.basename(root)

                # Check if the folder matches one of our defined weeks
                week_key = next((key for key in videos.keys() if key in folder_name), None)

                if week_key:
                    with open(file_path, "r", encoding="utf-8") as f:
                        content = f.read()
                    # Clean up old video blocks or placeholders if they exist
                    content = re.sub(r"### 🎥 סרטוני הדרכה.*?(?=\n#|\Z)", "", content, flags=re.DOTALL)
                    content = re.sub(r"### 🎥 סרטון.*?(?=\n#|\Z)", "", content, flags=re.DOTALL)

                    # Construct the new tabset block
                    vids = videos[week_key]
                   
Open data scored by Repobility · https://repobility.com
main function · python · L12-L60 (49 LOC)
Members/_template/intro.py
def main():
    # ===== ערוך כאן =====
    name = "Your Name"                   # שמך באנגלית
    degree = "B.A. Economics"            # התואר שלך
    university = "Your University"       # שם האוניברסיטה
    year_of_study = "2nd year"           # שנת לימודים
    economic_interests = [
        "כתוב כאן תחום כלכלי שמעניין אותך",
        "תחום נוסף",
        "תחום שלישי",
    ]
    why_econlab = (
        "כתוב כאן במשפט אחד למה הצטרפת ל-EconLab PPE "
        "ומה אתה מקווה ללמוד."
    )
    # ====================

    print("=" * 50)
    print("  EconLab PPE | היכרות ראשונה")
    print("=" * 50)
    print(f"  שם:          {name}")
    print(f"  תואר:        {degree}")
    print(f"  אוניברסיטה:  {university}")
    print(f"  שנה:         {year_of_study}")
    print()
    print("  תחומי עניין כלכליים:")
    for i, interest in enumerate(economic_interests, start=1):
        print(f"    {i}. {interest}")
    print()
    print("  למה EconLab?")
    print(f"    {why_econlab}")
    print("=" *
main function · python · L4-L36 (33 LOC)
Members/yehuda_saadya/intro.py
def main():
    name = "השם שלך באנגלית"
    degree = "התואר שלך (למשל: B.A Economics / M.A Public Policy)"
    location = "Israel"
    goal = (
        "להתמקצע בכלים תכנותיים לכלכלנים דרך עבודה מסודרת בניהול פרויקטים, "
        "כדי להבין באמת בפרקטיקה ולבנות יכולת ללמד אחרים."
    )
    mission = (
        "להקים 'סיירת כלכלנים' שיודעת לקחת נתונים ציבוריים, לנקות, לנתח, "
        "לבנות מודלים וכלים, ולהפיק תוצרים שמסייעים בקבלת החלטות."
    )
    focus_areas = [
        "Python לדאטה ואוטומציה (pandas, visualization)",
        "R לאקונומטריקה (regression, DiD, time series)",
        "SQL להבנת מסדי נתונים ושאילתות",
        "ניתוח תקציב המדינה ונתוני מאקרו (בנק ישראל, למ״ס, OECD)",
    ]

    print("=== EconLab PPE | Intro ===")
    print(f"Name: {name}")
    print(f"Degree: {degree}")
    print(f"Location: {location}")
    print()
    print("Why I'm here:")
    print(goal)
    print()
    print("My mission:")
    print(mission)
    print()
    print("Focus areas:")
    for i, item
generate function · python · L4-L46 (43 LOC)
scripts/generate_leaderboard.py
def generate():
    members_dir = "Members"
    scores = {}

    # Check if Members directory exists
    if os.path.exists(members_dir):
        # Iterate over student folders
        for student in os.listdir(members_dir):
            student_path = os.path.join(members_dir, student)
            if os.path.isdir(student_path):
                # Count unique assignment folders submitted by the student
                assignments = [d for d in os.listdir(student_path) if os.path.isdir(os.path.join(student_path, d))]
                scores[student] = len(assignments)

    # Sort students by score descending
    sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)

    # Generate Markdown content for Quarto
    md = [
        "---",
        "title: '🏆 לוח תוצאות'",
        "comments: false",
        "---",
        "",
        "כאן תוכלו לראות את ההתקדמות של חברי הקהילה! הלוח מתעדכן אוטומטית בכל פעם שסטודנט מגיש מחברת פתורה לתיקייה שלו.",
        "",
        "| מיקום | 
write_file function · python · L15-L20 (6 LOC)
setup_repo.py
def write_file(path: str, content: str) -> None:
    """יוצר קובץ עם תוכן בקידוד UTF-8 (יוצר תיקיות ביניים במידת הצורך)."""
    os.makedirs(os.path.dirname(path) if os.path.dirname(path) else ".", exist_ok=True)
    with open(path, "w", encoding="utf-8") as fh:
        fh.write(content)
    print(f"  [+] {path}")
make_dir function · python · L23-L26 (4 LOC)
setup_repo.py
def make_dir(path: str) -> None:
    """יוצר תיקייה (כולל הורים) אם לא קיימת."""
    os.makedirs(path, exist_ok=True)
    print(f"  [d] {path}/")
main function · python · L593-L634 (42 LOC)
setup_repo.py
def main() -> None:
    print("\n========================================")
    print("  EconLab PPE – Repository Initializer")
    print("========================================\n")

    # --- Root files ---
    print("[1/6] Root files...")
    write_file("README.md", ROOT_README)
    write_file("CONTRIBUTING.md", CONTRIBUTING)
    write_file(".gitignore", GITIGNORE)

    # --- Cookbook ---
    print("\n[2/6] Cookbook/...")
    make_dir("Cookbook")
    for path, content in COOKBOOK_FILES.items():
        write_file(path, content)

    # --- Notebooks ---
    print("\n[3/6] Notebooks/...")
    for folder, readme_content in NOTEBOOK_FOLDERS.items():
        make_dir(folder)
        write_file(os.path.join(folder, "README.md"), readme_content)

    # --- Projects ---
    print("\n[4/6] Projects/...")
    for folder, readme_content in PROJECT_FOLDERS.items():
        make_dir(folder)
        write_file(os.path.join(folder, "README.md"), readme_content)

    # --- Members ---
    print("\