예제 #1
0
        # did we make it to the end?
        if spins_left == 0:
            successes += 1
    return successes / n_simulations""")

    def _do_check(cls, fn):
        actual = fn(10, 10, 1000)
        assert actual == 1.0, "Expected slots_survival_probability(10, 10, 1000) to be 1.0, but was actually {}".format(
            repr(actual))

        actual = fn(1, 2, 10000)
        assert .24 <= actual <= .26, "Expected slots_survival_probability(1, 2, 10000) to be around .25, but was actually {}".format(
            repr(actual))

        actual = fn(25, 150, 10000)
        assert .22 <= actual <= .235, "Expected slots_survival_probability(25, 150, 10000) to be around .228, but was actually {}".format(
            repr(actual))


qvars = bind_exercises(
    globals(),
    [
        EarlyExitDebugging,
        ElementWiseComparison,
        BoringMenu,
        ExpectedSlotsPayout,
        SlotsSurvival,
    ],
)
__all__ = list(qvars) + ['play_slot_machine']
예제 #2
0
> The area of Finland is 338,000 km²  
> The area of Greenland is 2,166,000 km²
"""


class PrintPrintProblem(ThoughtExperiment):

    _hint = "Think about what happened when we called `help(abs(-2))` in the tutorial"

    _solution = """If you've tried running the code, you've seen that it prints:

    Spam
    None

What's going on here? The inner call to the `print` function prints the string "Spam" of course. The outer call prints the value returned by the `print` function - which we've seen is `None`.

Why do they print in this order? *Python evaluates the arguments to a function before running the function itself*. This means that nested function calls are evaluated from the inside out. Python needs to run `print("Spam")` before it knows what value to pass to the outer `print`."""


qvars = bind_exercises(
    globals(),
    [
        RoundFunctionProblem,
        RoundNdigitsProblem,
        # XXX: need a placeholder here for problem that has no interactivity
        DummyProblem,
        PrintPrintProblem,
    ],
)
__all__ = list(qvars)
예제 #3
0
    return hand


def gen_bj_inputs(n):
    random.seed(1)
    return [(gen_bj_hand(), gen_bj_hand()) for _ in range(n)]


class BlackjackCmp(FunctionProblem):
    _var = 'blackjack_hand_greater_than'
    _hint = (
        "This problem is a lot easier to solve if you define at least one 'helper' function."
        " The logic for calculating a hand's total points is a good candidate for extracting into a helper function."
    )
    _solution = CS.load(bj_module.__file__)

    _test_cases = [(args, hand_gt_soln(*args)) for args in gen_bj_inputs(100)]


qvars = bind_exercises(
    globals(),
    [
        JimmySlots,
        LuigiAnalysis,
        BlackjackCmp,
        DummyProblem,
    ],
    start=1,
)
__all__ = list(qvars)
예제 #4
0

    # TODO: would nice to have an injection decorator for this kind of thing,
    # but I'm not sure how well it would work with the existing magical
    # metaclass method decoration :/
    def simulate_one_game(cls):
        phit = cls._get_injected_args()[0]
        game = BlackJack(phit, True)
        game.play()

    def simulate(cls, n_games=100):
        phit = cls._get_injected_args()[0]
        wins = 0
        for _ in range(n_games):
            wins += 1 == BlackJack(phit).play()
        print("Player won {} out of {} games (win rate = {:.1%})".format(
            wins, n_games, wins/n_games
            ))

qvars = bind_exercises(globals(), [
    SignFunctionProblem,
    PluralizationProblem,
    WeatherDebug,
    ConciseIsNegative,
    HotDogGauntlet,
    OneTopping,
    BlackJackProblem,
    ],
)
__all__ = list(qvars)
예제 #5
0
The above implementation relies on the fact that `list.index` returns the index of the *first* occurrence of a value. (You can verify this by calling `help(list.index)`.) So if, after sorting the list in ascending order, the value 0 is at index 0, then the number of negatives is 0. If 0 is at index 2 (i.e. the third element), then there are two elements smaller than 0. And so on.

*Note*: it's usually considered "impolite" to modify a list that someone passes to your function without giving them some warning (i.e. unless the docstring says that it modifies its input). So, if we wanted to be nice, we could have started by making a copy of nums using the `list.copy()` method (e.g. `our_nums = nums.copy()`), and then working with that copy rather than the original.

If you're a big Lisp fan (and based on the pre-challenge survey I know there's at least one of you out there!) you might have written this technically compliant solution (we haven't talked about recursion, but I guess this doesn't use any syntax or functions we haven't seen yet...):

```python
def count_negatives(nums):
    # Equivalent to "if len(nums) == 0". An empty list is 'falsey'.
    if not nums:
        return 0
    else:
        # Implicitly converting a boolean to an int! See question 6 of the day
        # 3 exercises.
        return (nums[0] < 0) + count_negatives(nums[1:])
```"""


qvars = bind_exercises(
    globals(),
    [
        SelectSecondItem,
        LosingTeamCaptain,
        PurpleShell,
        UnderstandLen,
        FashionablyLate,
        CountNegativesRiddle,
    ],
)
__all__ = list(qvars)
예제 #6
0
odds = evens = []
for i in range(5):
    if (i % 2) == 0:
        evens.append(i)
    else:
        odds.append(i)
print(odds)
print(evens)```

We might expect this would print `[1, 3]`, then `[0, 2, 4]`. But actually, it will print `[0, 1, 2, 3, 4]` twice in a row. `evens` and `odds` refer to the same object, so appending an element to one of them appends it to both of them. This is occasionally the source of hair-pulling debugging sessions. :)

Another consideration is expressions that have side effects. For example, `list.pop` is a method which removes and returns the final element of a list. If we have `L = [1, 2, 3]`, then `a = b = L.pop()`, will result in `a` and `b` both having a value of 3. But running `a = L.pop()`, then `b = L.pop()` will result in `a` having value 3 and `b` having value 2.
"""


qvars = bind_exercises(
    globals(),
    [
        ExerciseFormatTutorial,
        CircleArea,
        VariableSwap,
        ArithmeticParens,
        CandySplitting,
        MysteryExpression,
        QuickdrawGridProblem,
        SameValueInitializationRiddle,
    ],
    start=0,
)
__all__ = list(qvars)
예제 #7
0
class RouletteAnalyzer(FunctionProblem):
    _var = 'conditional_roulette_probs'

    _solution = CS.load(rou_module.__file__)

    _test_inputs = [
        [1, 3, 1, 5, 1],
        [
            1,
            1,
            1,
            1,
        ],
        [1, 2, 1],
        [5, 1, 3, 1, 2, 1, 3, 3, 5, 1, 2],
    ]

    _test_cases = [(args, roulette_gt(args)) for args in _test_inputs]


qvars = bind_exercises(
    globals(),
    [
        LightningLen, ZipValidator, WordSearch, MultiWordSearch, DiamondArt,
        RouletteAnalyzer
    ],
    start=0,
)
__all__ = list(qvars)
예제 #8
0
    _var = 'smallest_stringy_number'

    _test_cases = [
        (('1', '2', '3'), '1'),
        (('10', '2', '3'), '2'),
        (('2', '3', '10'), '2'),
        (('-100', '10', '5'), '-100'),
    ]

    _hint = "Remember that `min` can optionally take a `key` argument representing a function to apply to each element before comparing them."
    _solution = CS('return min(s1, s2, s3, key=int)')


SmallestStringyProblem = MultipartProblem(SmallestStringyDebug,
                                          SmallestStringyFix)

qvars = bind_exercises(
    globals(),
    [
        RoundFunctionProblem,
        RoundNdigitsProblem,
        CandySmashingFunctionProblem,
        DummyProblem,  # Reading exceptions
        TimeCallProblem,
        SlowestCallProblem,
        PrintPrintProblem,
        SmallestStringyProblem,
    ],
)
__all__ = list(qvars)