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
To apply array indexing in numpy
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.
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 inpyodide
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.