How to generate automatically an interactive exercise in html with python

If you know my blog, you will know that I like to create programs that makes exercises. This one will create an exercise in html and javascript with the help of python to generate random text for the exercises.

The python code has three functions:

- RANDOM PART OF THE EXERCISE           genex()
- GENERATE EXERCISE's TEXT              printex()
- GENERATE THE HTML CODE WITH EXERCISE  show()

The show function does this

    1. Starting html code of the page with the script that 
    checks the solution.

    2. After the script there is some html code to introduce
    the exercises.

    3. At the end of this script, before the call to this function show,
    there is the call to printex for 10 time = 10 random exercises

    Each time printex is called it choose 1 of 2 way of presenting the exercise.
    The multiline strings takes random values generated by genex() a function
    that creates and returns a dictionary with the keys corresponding to
    the random parts of the text of the excercise.

This is the entire code:

import random
import os

'''          INDEX
	- RANDOM PART OF THE EXERCISE           genex()
	- GENERATE EXERCISE's TEXT              printex()
    - GENERATE THE HTML CODE WITH EXERCISE  show()



'''


tmp = "Calcola l'interesse su 10.000 € al tasso del 7% per 1 anno."


# ======================= RANDOM ELEMENTS OF THE 
#                         TEXT OF THE EXERCISE =====


def genex() -> dict:
	''' returns a dictionar with the random data to insert in the text of the exercise'''
	s = {
		"random_start": random.choice([
			"Trova il",
			"A quanto ammonta il",
			"Calcola il",
			"Calcolare il",
			"Trovare il",
			"Devi trovare il",
			"Fai il calcolo del"

			])
	}
	# valore delle merci
	merci = s["valore_merci"] = random.randrange(100, 1000, 100)
	mese_pag = random.randint(6,12)
	acquista = mese_pag - 2

	# data del pagament
	s["mese_pag"] = random.choice(["giugno", "luglio", "agosto", "settembre", "ottobre", "novembre", "dicembre"])
	# data dell'acquisto
	s["mese_acquisto"] = random.choice([
		"gennaio", "febbraio", "marzo", "aprile", "maggio"
		])

	# Guadagn
	vend = s["percentuale_vendite"] = random.randrange(50, 80, 10)
	ric = s["perc_ricarico"] = random.randrange(25, 50, 10)
	costo_venduto = merci * vend / 100
	prezzo_venduto = costo_venduto + costo_venduto * ric / 100

	r = s["prezzo_venduto"] = str(prezzo_venduto)

	if int(prezzo_venduto) == prezzo_venduto:
		s["prezzo_venduto"] = str(r).split(".")[0]
	else:
		s["prezzo_venduto"] = r + "#" + r.replace(".", ",") +  "#" + r + "0" + "#" + r.replace(".", ",") + "0"
	return s


	# ======================= TEXT OF THE 
	#                         EXERCISE ================

def printex() -> str:
	''' Returns a string with the text of the exercise, chosen among 2 type of text
	that contains random parts from a dictionary generated by genex() '''
	s = genex()
	x = random.choice([1,2])
	match x:
		case 1:
			inp = """input("{random_start} valore delle merci acquistate il primo {mese_acquisto} al prezzo di {valore_merci} € delle quali il primo {mese_pag} si vende il {percentuale_vendite} % applicando un ricarico del {perc_ricarico} %.", "{prezzo_venduto}");""".format(**s)
		case 2:
			inp = """input("Sapendo che un'azienda ha acquistato merci il primo {mese_acquisto} pagandole {valore_merci} €, calcola quanto incasserà al momento del pagamento delle stesse concordato per il primo di {mese_pag}, data in cui ha venduto il {percentuale_vendite} % delle merci. Il ricarico sulle merci vendute è pari al {perc_ricarico} %", "{prezzo_venduto}");""".format(**s)


	return inp



def show():
	'''
		Explanation of this code

		1. Starting html code of the page with the script that 
		checks the solution.

		2. After the script there is some html code to introduce
		the exercises.

		3. At the end of this script, before the call to this function show,
		there is the call to printex for 10 time = 10 random exercises

		Each time printex is called it choose 1 of 2 way of presenting the exercise.
		The multiline strings takes random values generated by genex() a function
		that creates and returns a dictionary with the keys corresponding to
		the random parts of the text of the excercise.


	'''


	html = """



Fabbisogno 1

Il fabbisogno finanziario dipende anche dalle risorse finanziarie necessarie all'impresa per la gestione corrente. Controlliamo in questi esercizi se l'ammontare delle risorse derivanti dalle vendite sono sufficienti a far fronte ai debiti per gli acquisti. Di solito le imprese chiedono ai fornitori di poter pagare ad una certa data le merci acquistate, in modo da poter ottenere, nel frattempo, le risorse vendendo i prodotti acquistati. Probabilmente non riusciranno a vendere tutte le merci, ci sarà sempre una parte che rimane in magazzino, ma il prezzo di vendita è superiore a quello di acquisto, per cui, se il ricarico (l'aumento del prezzo rispetto a quello di acquisto) copre il costo delle merci invendute, l'impresa non avrà bisogno di ulteriori risorse finanziarie. Al contrario, dovrà chiedere un prestito oppure una ulteriore dilazione nel pagamento della differenza tra il valore delle merci acquistate e quello delle merci vendute. " with open("fabbisogno1.html", "w", encoding="utf-8") as file: file.write(html) os.startfile("fabbisogno1.html") show()

This is the html code generated in action

Fabbisogno 1

Il fabbisogno finanziario dipende anche dalle risorse finanziarie necessarie all'impresa per la gestione corrente. Controlliamo in questi esercizi se l'ammontare delle risorse derivanti dalle vendite sono sufficienti a far fronte ai debiti per gli acquisti. Di solito le imprese chiedono ai fornitori di poter pagare ad una certa data le merci acquistate, in modo da poter ottenere, nel frattempo, le risorse vendendo i prodotti acquistati. Probabilmente non riusciranno a vendere tutte le merci, ci sarà sempre una parte che rimane in magazzino, ma il prezzo di vendita è superiore a quello di acquisto, per cui, se il ricarico (l'aumento del prezzo rispetto a quello di acquisto) copre il costo delle merci invendute, l'impresa non avrà bisogno di ulteriori risorse finanziarie. Al contrario, dovrà chiedere un prestito oppure una ulteriore dilazione nel pagamento della differenza tra il valore delle merci acquistate e quello delle merci vendute.

https://github.com/formazione/JavaScript_QUIZ.git

Quiz made for numbers

import random
import os

'''          INDEX
	- RANDOM PART OF THE EXERCISE           genex()
	- GENERATE EXERCISE's TEXT              printex()
    - GENERATE THE HTML CODE WITH EXERCISE  show()



'''


tmp = "Calcola l'interesse su 10.000 € al tasso del 7% per 1 anno."


# ======================= RANDOM ELEMENTS OF THE 
#                         TEXT OF THE EXERCISE =====


def genex() -> dict:
	''' returns a dictionar with the random data to insert in the text of the exercise'''
	s = {}
	s["first"] = random.randrange(10, 100)
	s["second"] = random.randrange(10, 100)
	result = s["first"] + s["second"]
	virgola = f"#{float(result)}"
	virgola0 = f"#{virgola}0"
	punto = virgola.replace(".", ",")
	punto0 = punto + "0"
	comma1 = f"#{result:,}"
	comma1_0 = comma1 + ".0"
	comma1_00 = comma1 + ".00"
	comma2 = comma1.replace(",",".")
	comma2_0 = comma2 + ",0"
	comma2_00 = comma2 + ",00"

	result = str(result) + virgola + virgola0 + punto + punto0 + comma1 + comma1_0 + comma1_00 + comma2 + comma2_0 + comma2_00
	s["result"] = result
	return s


	# ======================= TEXT OF THE 
	#                         EXERCISE ================

def printex() -> str:
	''' Returns a string with the text of the exercise, chosen among 2 type of text
	that contains random parts from a dictionary generated by genex()
	
	the code will generate more solution, so that you can use the , or the .
	if you are in a country where you use different type of sign for that

	'''
	s = genex()
	x = random.choice([1,2])
	match x:
		case 1:
			inp = """input("How much is {first} plus {second}", "{result}");""".format(**s)
		case 2:
			inp = """input("Give the result of {first} plus {second}", "{result}");""".format(**s)
	return inp



def show():
	'''
		Explanation of this code

		1. Starting html code of the page with the script that 
		checks the solution.

		2. After the script there is some html code to introduce
		the exercises.

		3. At the end of this script, before the call to this function show,
		there is the call to printex for 10 time = 10 random exercises

		Each time printex is called it choose 1 of 2 way of presenting the exercise.
		The multiline strings takes random values generated by genex() a function
		that creates and returns a dictionary with the keys corresponding to
		the random parts of the text of the excercise.


	'''


	html = """
<style>
	.fontbig {
		font-size: 1.5em;
	}

/**
Code By Web Dev Trick ( https://webdevtrick.com )
For More Source Code Visit Our Blog ( https://webdevtrick.com )
**/
 
body, html {
 background: #ECEDEF;
 margin-left: 10%;
 margin-right: 10%;
 padding: 0;
}
 

</style>
<!-- <html oncontextmenu="return false;"> -->
<script>

// ======================== CHECK ======================= >
function check(casella, giusta, num){
	// the solutions are good both for low and capital letters

	if (giusta.split("#").includes(casella.value)){

		casella.style.background = 'yellow';
		return casella.value;
	}
	else{
		casella.style.background = 'red';
	}
	console.log(giusta);
	// console.log(casella.value.split("#));
} // ====================================== CHECK === !

function print_it(parola){
	if (soluzioni.innerHTML.includes(parola)){
	}
	else {
    	soluzioni.innerHTML += " - " + parola;
	}
}

var countdom = 1;
function input(domanda, giusta){
	var dom_h2 = "<table style='background:#fcab41;'><td><p class='fontbig' style='color: blue'>" + countdom++ + " " + domanda;
	var part1 = dom_h2 + "<i style='color:red'></i><br><input id='casella' class='fontbig' type=text class='t1' placeholder='?...' onchange=\\"if (check(this,'";
	part1 += giusta + "')){print_it(this.value)};\\" style='text-align:right'/></center></p></table>";
	document.write(part1);
	}
	

x = document.getElementsByClassName('t1');
for (i of x){
    i.value = "";
}

</script>
<h1>Maths</h1>

Doing sums

<script>
		"""

	for x in range(10):
		html += printex()
	html += "</script>"
	with open("fabbisogno1.html", "w", encoding="utf-8") as file:
		file.write(html)
	os.startfile("fabbisogno1.html")

show()

Subscribe to the newsletter for updates
Tkinter templates
Avatar My youtube channel

Twitter: @pythonprogrammi - python_pygame

Videos

Speech recognition game

Pygame's Platform Game

Other Pygame's posts

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.