In a project-based setting for students with code background, I make assignments in Jupyter notebooks. (I would also be happy to use RMarkdown for this purpose, but I personally use Jupyter more often.)

Basic Probability Simulations: Making Sense of Probability in Implementation

I assigned this activity, and others like it, to an undergraduate student I was mentoring. They had taken a discrete math class and introductory Python, but were interested in learning probability theory, especially with respect to Markov processes on graphs. These assignments were accompanied by weekly meetings and assigned readings.