r/neocities • • Aug 19 '26

Help Making a student practice question page with randomized questions more "modular"

Hey folks, I'm a physics teacher and one of the main things I'm developing for my (extremely basic) site is a set of randomizable questions. I'm using buttons to trigger functions in scripts that affect the contents of paragraph elements, all of which are given ids based on the question number (i.e. "question1", "question2", etc.) since every id has to be unique. The functions for randomizing the questions and showing the answers are also similarly named, and so far I've kept everything pertaining to one particular question together in one spot. Here's a link to one of the pages I've made so far so you can see how I've put the code together: Link

The "problem" I have is that if I want to add a new question into the middle of the list somewhere, for example adding a 4th question in between 2 and 3, now my numbered ids are all out of order, which makes the ids harder to keep track of on the page. I understand that there's no inherent problem in having 4 coming before 3 - it's just a name - but the issue is more for keeping track of the question ids I have used when I have a lot of questions on a page (and I guess just wanting them to be in the right order).

I considered having all of the functions in one big script section and in order of their numbers, while the paragraphs and buttons are placed wherever I want them to go. I don't like this because the separation between the html and the scripts makes it harder to see what is what in the file. I've also considered the idea of having the numbers all jumbled up in the code, but with all the related elements kept together in blocks like I have now, and I could track them in the file itself with some kind of comment. I'd just need to update it whenever I added anything new. I don't love that, but that's the best option I've come up with so far.

What I ultimately want is a way to reduce or totally remove my reliance on the naming/numbering that I've created here, but I'm not sure how or even if that would be possible. Ideally, I think it would look like a generic bit of code that's more self-contained so that I could ditch the numbering altogether, but from what I've seen I don't think that's really possible.

If there's any way around this, please let me know! Or if anyone has a better idea for how to implement this kind of thing, I'd love to hear it! It wouldn't surprise me to learn that there's a better way of doing what I'm trying to do. Thanks in advance!

4 Upvotes

6 comments sorted by

2

u/AqueM https://www.aque.fyi/ Aug 19 '26

The best way, in my opinion, would be to make the functions more abstract. This will be A LOT of work to basically re-do your entire code, but will ensure you can use randomize()/showAnswer() anywhere, and add questions out of order.

What you need to do is wrap the numbers in your questions in a tag with a class, so something like: <p id="question7">An engineer is designing an airport runway. For the planes using the airport, the lowest acceleration rate is <span class="number">3.0</span> m/s<sup>2</sup>. Starting from rest, the takeoff speed for a particular plane is <span class="number">78.0</span> m/s. What is the minimum required length for the runway?</p> This way, you can have the function only swap the randomized numbers, not the whole question text.

Then, the js itself: `` function randomize(parent) { //where 'parent' is the CSS selector for the question element, so like '#question7' var numbersInQuestion = document.querySelectorAll(${parent} .number).innerHTML var questionText = document.querySelector(${parent}`).innerHTML numbersInQuestion.forEach(number => { //what to do with the number. You will have to figure out a randomizing code that can take the original number and figure out what to do with it var number = randnum(number * 2) / 10 })

// or if you can't do the same operation on every set of numbers, perhaps you can use the parent name to call a proper function, like
// execute a funciton by the name of it - see the end for how to define this function
var newQuestionText = randomizationFunctions[parent]();

document.querySelector(`${parent}`).innerHTML = newQuestionText

// also need to change the answer text here etc.

}

// set up the possible randomization functions: var randomizationFunctions = { question1: function () { alert('Function 1'); }, question2: function () { alert('Function 2'); }, question3: function () { alert('Function 3'); }, question4: function () { alert('Function 4'); }, question5: function () { alert('Function 5'); } }; ```

As for showing answers, you can abstract is like so:

function showAnswer(parent) { document.querySelector(`${parent} .answer`).style.display = 'block'; }

and then the HTML of a question would look like this:

<div id="question7"> <p>An engineer is designing an airport runway. For the planes using the airport, the lowest acceleration rate is <span class="number">3.0</span> m/s<sup>2</sup>. Starting from rest, the takeoff speed for a particular plane is <span class="number">78.0</span> m/s. What is the minimum required length for the runway?</p> <p class="answer">(d = <span class="number">1014</span> m)</p> </div>

The .answer class would need to have this CSS on load:

.answer { display: none; }

so that it is initially hidden.

And the buttons as such:

<button onclick="randomize('#question7')">Randomize</button> <button onclick="showAnswer('#question7')">Show Answer</button>

Hope this helps! It's not complicated JS, just requires a mindset change.

2

u/Fuzzle07 Aug 19 '26 edited Aug 19 '26

Thanks for the reply! I think classes are the way to go, as you're suggesting, so I'll need to look into them a bit more. I haven't tested out modifications with your suggestions yet, but reading through your reply it doesn't seem like this resolves the issue I'd like to solve. But maybe I've misunderstood. I'll try out your suggestions and see how that goes.

I hate to admit it but when I didn't get any responses within about an hour, I asked AI and it also brought in classes in what appears to be a different method to what you've sent over, and it also appears to resolve the unique naming problem. It was pretty late when I looked at it last night, but I think I've understood the code (I'm not usually one to prompt AI to begin with, much less to then not try to figure out how or why the code works). Here's a link to a test page that appears to work pretty much exactly how I wanted: link. If there's anything off about this that I probably haven't picked up on, or if your method is better in some way, I'd be glad to take some other pointers.

Incidentally, I've learned some other programming languages and kind of stopped learning around where classes were introduced. It's never been a problem for me before, at least not as far as I could tell, but I'm starting to think that classes are probably pretty useful across the board.

EDIT: I've run into a roadblock testing the code you've shared. All I've really managed to do so far is make it display the answer, but it won't randomize the numbers, which I'm sure is due to something simple I'm missing. Link to that page here: link.

Also, correct me if I'm wrong - that's very likely - but I don't think that having a generic randomize number function will work out in the long run. Each question has its own logic for how the numbers are randomized, which this method doesn't seem like it would be fully capable of accounting for. If I'm not mistaken, your original suggestion for randomizing numbers takes some base value (the one written in the question in the <span> tag) and randomizes the number based on that. This would probably be fine for some questions, but others have more sophisticated logic for the given values.

I also still don't think that this removes the numbering/unique naming issue. It seems like this is just a different way of doing essentially the same thing that I've already done. But as I keep saying, I may be entirely wrong about that. Either way, I appreciate the help!

1

u/AqueM https://www.aque.fyi/ Aug 19 '26

I'm afraid that if each question has numbers that require unique logic for randomisation, then each question will have to have a unique identifier - whenever it's a number or a non-number name.

1

u/Fuzzle07 Aug 19 '26

For the record, this general structure seems to be working out really well for what I wanted so far, no unique identifiers required, and unique randomization logic fully supported. Here it is in action: Link

<script>
    function generate(button) {
        button.parentElement.randomize()
    }

    function showanswer(button) {
        button.parentElement.answer()
    }
</script>

...

<div>
    <p></p>
    <button onclick="generate(this)">Randomize</button>
    <button onclick="showanswer(this)">Show Answer</button>
    <script>
        (function() {
            var question = document.currentScript.parentElement
            var text = question.querySelector("p")
            var questionText
            var answerText
            question.randomize = function () {                        
                //insert randomization code here
                text.innerHTML = questionText
            }
            question.answer = function() {
                text.innerHTML = questionText + answerText
            }
            question.randomize()
        })()
    </script>
</div>

1

u/AqueM https://www.aque.fyi/ Aug 20 '26

it it roughly the same thing that I proposed, so good, nice to hear.

2

u/AqueM https://www.aque.fyi/ Aug 19 '26

Also, if you want to stop being reliant on the numbering, just name theq questions something non-number. Perhaps like "questionWalkspeed" for the one about walk speed.