Skip to editor
File
New File Ctrl+N
New Folder

Save Ctrl+S
Upload File…
Download as ZIP

Delete File

Reset Files…
View
Toggle Sidebar Ctrl+B
Toggle Terminal Ctrl+`

Word Wrap Alt+Z

Exercise Info

Theme: Dark
Font Size: 14px
Reading Mode: Default
Run
Run Code Ctrl+Enter
Save & Run F5

Clear Output
Help
Keyboard Shortcuts ?
CS 477: Module 1: Numpy Exercise (1.5 pts)
Explorer
GitHub

Connect to GitHub to push and pull your project files to a repository.

On the page that opens, create a token with repo scope, copy it, then paste it below.

Paste the personal access token you created on GitHub with repo scope.

Click Refresh to load commit history
Exercise Info

Goals

  1. To apply array indexing in numpy
  2. To use for loops in numpy

Instructions

The code below does one trial (experiment) of the 10 heads in a row game, but that doesn't give us a very good idea of how long it takes in general. We should do the experiment many times to get a better sense. Your task in this exercise is to put the starter code inside of a for loop that loops through num_trials times and stores the number of flips it took for each trial as an element in the trials numpy array. All you should have to do is add a for loop, put all of the code inside, and assign num_flips to an index in trials. Then, we can use the power of matplotlib to plot a histogram showing us a distribution of the number of heads it took over all experiments.



The Ursinus-WebIDE by Chris Tralie (opens in new tab) and Bill Mongan (opens in new tab)

Your browser does not support WebGL. A graphical rendering canvas would appear here.


          
No suggestions. Code quality feedback will appear here.
Run your code to inspect variables.
Click Step Run above to record execution steps. Available for Python.

Run your code to see the function-call tape.

For Python, calls are recorded automatically (use Step Run on the Inspector toolbar).

For JavaScript or Java (Processing), you have to record the markers yourself. These helpers are labels — they don't call any function, they only annotate this tape.

Option 1 — sibling log (simple). Call webideTrace.tap('name', arg1, arg2) once per event. Each tap shows up as a flat sibling. Use this when you just want to know "did this code run?" or "in what order did these run?".

Option 2 — scope tracking (for nested / recursive calls). Put webideTrace.call('name', args…) as the first line inside the function body, and webideTrace.return(value) immediately before every return statement (or once at the end if the function is void). Then call the function normally from outside.

// JavaScript example
function fact(n) {
    webideTrace.call('fact', n);          // at the top
    if (n <= 1) {
        return webideTrace.return(1);     // wrap every return
    }
    let r = n * fact(n - 1);
    return webideTrace.return(r);
}
fact(4);   // now the tape shows fact(4) → fact(3) → fact(2) → fact(1)

Every call must be matched by a return. If you put three calls in a row without returns, each one ends up nested inside the previous (which is what the IDE will warn about with "no .return"). For that case use tap instead.

Not logged in pyodide
Ln 1, Col 1
Keyboard Shortcuts

Editing & Files

Save current fileCtrlS
Run codeCtrlEnter
Save and RunF5
Toggle word wrapAltZ

View

Toggle sidebarCtrlB
Toggle terminal panelCtrl`
Focus ExplorerCtrlShiftE
Focus Terminal tabCtrlShiftT
Focus Output tabCtrlShiftO
Focus Suggestions tabCtrlShiftP

Editor Font

Increase font sizeCtrl=
Decrease font sizeCtrl-

Help

Show this dialog?
Close any dialogEsc

Tip: Within an input field, "?" types a literal question mark. Press Esc first to leave the field, then press ? to open this dialog.

import io, base64 img_str = "" def save_figure_js(): global img_str buf = io.BytesIO() plt.savefig(buf, format='png') buf.seek(0) img_str = "data:image/png;base64,{}".format(base64.b64encode(buf.read()).decode('UTF-8')) audio_sav_arr = [] audio_sav_sr = 44100 def save_audio_js(arr, sr): global audio_sav_arr global audio_sav_sr audio_sav_arr = np.array(arr).tolist() audio_sav_sr = sr PYODIDE_COUT = "" def pyodide_print(s): global PYODIDE_COUT PYODIDE_COUT += s
import sys as _webide_sys _webide_steps = [] _webide_calltree = {'name': '<module>', 'args': '', 'children': [], 'returnValue': None, 'exception': None, 'lineno': 0} _webide_call_stack = [_webide_calltree] _webide_STEP_LIMIT = 2000 _webide_CALL_LIMIT = 2000 _webide_call_count = [0] def _webide_safe_repr(v, limit=80): try: if isinstance(v, (int, float, bool)) or v is None: return str(v) if isinstance(v, str): s = v if len(v) < limit else v[:limit] + '...' return repr(s) if callable(v): return '<function ' + getattr(v, '__name__', '?') + '>' s = repr(v) return s if len(s) < limit else s[:limit] + '...' except Exception: return '<unrepresentable>' def _webide_tracer(frame, event, arg): try: # Pyodide's pyodide.runPython is itself implemented in Python — it # parses, compiles, and AST-walks the student source via eval_code / # generate_tokens / deepcopy / iter_fields / etc. Without a filter, # settrace records all of THAT internal machinery and the tape fills # with hundreds of iter_child_nodes/_make/deepcopy frames before the # student code ever runs. The runPython call site tags student # source with a unique co_filename ('<webide-student>') so we can # accept ONLY those frames here and skip everything else (returning # None from a global trace function tells CPython not to install a # local tracer for that frame, but child frames still pass through # this global tracer — so we filter each one independently). co_fname = frame.f_code.co_filename or '' if co_fname != '<webide-student>': return None fname = frame.f_code.co_name lineno = frame.f_lineno if event == 'line' and len(_webide_steps) < _webide_STEP_LIMIT: locs = {} for k, v in frame.f_locals.items(): if k.startswith('_webide') or k.startswith('__'): continue locs[k] = {'type': type(v).__name__, 'value': _webide_safe_repr(v)} _webide_steps.append({'lineno': lineno, 'function': fname, 'locals': locs}) elif event == 'call' and _webide_call_count[0] < _webide_CALL_LIMIT: _webide_call_count[0] += 1 args = [] try: for k, v in frame.f_locals.items(): if k.startswith('__'): continue args.append(k + '=' + _webide_safe_repr(v, 40)) except Exception: pass node = {'name': fname, 'args': ', '.join(args[:6]), 'children': [], 'returnValue': None, 'exception': None, 'lineno': lineno} _webide_call_stack[-1]['children'].append(node) _webide_call_stack.append(node) elif event == 'return': if len(_webide_call_stack) > 1: _webide_call_stack[-1]['returnValue'] = _webide_safe_repr(arg) _webide_call_stack.pop() elif event == 'exception': if len(_webide_call_stack) > 0: try: _webide_call_stack[-1]['exception'] = _webide_safe_repr( arg[1] if isinstance(arg, tuple) else arg) except Exception: _webide_call_stack[-1]['exception'] = '<exception>' except Exception: pass return _webide_tracer # NOTE: settrace is NOT installed here. The JS-side step runner sets # _webide_student_source and runs pyodideStepExec, which installs settrace # only around the student code — preventing Pyodide's eval_code / compile / # AST machinery from being recorded as part of the call tape.
_webide_compiled = compile(_webide_student_source, '<webide-student>', 'exec') _webide_sys.settrace(_webide_tracer) try: exec(_webide_compiled, globals()) finally: _webide_sys.settrace(None) del _webide_compiled, _webide_student_source
# kept for backwards compat with any callers that still invoke it _webide_sys.settrace(None)