mas.to is one of the many independent Mastodon servers you can use to participate in the fediverse.
Hello! mas.to is a fast, up-to-date and fun Mastodon server.

Administered by:

Server stats:

12K
active users

#stack

2 posts2 participants0 posts today
Replied in thread

@looopTools

Fair enough. Because recursion always has a limit, in any language, the tutorials probably assume you're aware of this already. The specific limit in Python is adjustable, but there's no way to eliminate it altogether.

Do the tutorials actually include data/examples that run into the recursion limit? Or is it only when applying code like that to other data that you run into issues?

I ask because the easiest way to smash the limit is to create a cyclic data structure, which is trivial in Python. If you naively recurse such an object, it goes on forever - until it hits the configured limit or the machine runs out of memory, anyways. i.e. this case:

>>> foo = ["bar"]
>>> foo.append(foo)
>>> foo
['bar', [...]]

If you think it's possible your recursion code might have to deal with something like this, you usually end up keeping track of the objects you've already processed, and skip them if you see the same object again (typically by the object ID).

In many cases, you can also rewrite recursive code so that it's not recursive, and cannot run into this problem. As a bonus, problems that can be refactored this way usually run faster without the recursion.

Today's work. Sorry, murky low light photo, finished at sunset as usual.

Still space for more!

Can see the difference between birch and alder nicely there. The orangey stuff on the right is alder. Slightly less energy than birch but easier to light. Good firewood and what mostly grows in our forest as it thrives in the swampy parts near the river.

Those last two stacks are from a few fallen trees that were blocking the forest road.

STACK Webinar video

The video from my #Moodle Academy webinar on #maths education using the #STACK question type. I do get quite excited during the presentation. I can make all sample questions available on request. I amused myself again when I heard me mention what I would do if I were/was independently wealthy.

youtube.com/watch?v=JdLkb2dder

Here is the hosting service we offer

catalyst-eu.net/service/moodle

(but it is all #GPL )

Julik Tarkhanov · UI Algorithms: A Tiny Undo StackI’ve needed this before - a couple of times. Third time I figured I needed something small, nimble - yet complete. And - at the same time - wondering about how to do it in a very simple manner. I think it worked out great, so let’s dig in. Most UIs will have some form of undo functionality. Now, there are generally two forms of it: undo stacks and version histories. A “version history” is what Photoshop history gives you - the ability to “paint through” to a previous state of the system. You can add five paint strokes, and then reveal a stroke you have made 4 steps back. But most apps won’t need that. What you will need is an undo stack, which can be specced out as follows: An undoable action gets performed and gets pushed onto the stack. If undo is requested, the stack is popped and the rollback action gets applied for the popped action. If an action was undone, you can redo that action. If you have undone 2 actions, you can redo 2 actions. If you push an undoable action onto the stack in presence of actions that can be redone, they get discarded - there is no branching, remember? If you are curious how “the big guys” used to do it - check out the NSUndoManager documentation So, as I usually like to do, I want to understand the API that would be optimal. For this use case - drawing - I had the following workflow: When you draw a stroke the input points get added to currentStroke When you release the pen the currentStroke gets appended to strokes and reset for the next stroke. I wanted something like this: let addStroke = () => strokes.push(currentPaintStroke); let removeStroke = () => strokes.pop(); undoThing.push(addStroke, removeStroke); // then, on user action undoThing.undo(); // calls removeStroke() undoThing.redo(); // calls strokes.push(...) again The perils of stack pointers Simplest thing in the world. Now, if you look at most recommended (and some existing!) implementations of an undo stack, you will find they usually make use of a stack with a pointer. Like here and here - you would have a stack, usually represented as a JS array, and some kind of pointer or an index that you would use to index into it. And while it is workable and standard, it just didn’t jive with me well. See, using an index into an array usually makes JS code susceptible to two things, which bite me every single time: Indexing into a nonexistent index - hello undefined checks Mistakes in offsets when calling Array.slice and Array.splice. Oh, and confusing slice and splice, of course. The fact that Ruby and JS have different semantics for slice - one uses the index bounds, the other uses two offsets - doesn’t help things. And what happens if an API uses offsets into a vector? Exactly: confusion whether those offsets are inclusive or exclusive. Oh, and the offsets change after you mutate the array, which makes it even more painful. Could we not index? So what came to mind was this: we effectively have two stacks, not one. We have an undoStack (things that can be rolled back) and a redoStack - things that can be rolled forward. All the things we do with our undo-redo actions actually do not change the pointer - they move things from one stack to another. And rules change between these two stacks! We erase the redoable actions when we add a new undoable action, remember? So while an undoable stack will rarely get “nullified”, the redoable stack likely will be nullified frequently. Once this became clear, the implementation practically wrote itself: function createUndoStack() { let past = []; let future = []; return { push(doFn, undoFn) { doFn(); past.push({doFn, undoFn}); // Adding a new action wipes the redoable steps future.length = 0; }, undo() { let action = past.pop(); if (action) { action.undoFn(); future.unshift(action); } }, redo() { let action = future.shift(); if (action) { action.doFn(); past.push(action); } } }; } So instead of trying to save resources by having just one array (and miserably failing with off-by-one index errors), we can embrace dynamically sized arrays and just forget indices altogether. Neat! Let’s add a couple more methods to display our UI: get canUndo() { return past.length > 0; }, get canRedo() { return future.length > 0; } The call-by-sharing problem There is a catch with our implementation though. JS has rather interesting lexical scoping rules: what is defined in the scope of the definition of the function will be referenced from within the function. This means that when we start pulling a new currentStroke our undoFn closure will not use a copy of the currentStroke it was created with, but our current one. And our doFn and undoFn must satisfy an important guarantee: they must be idempotent. No matter what the state of the surrounding system is, appending the currentStroke should always append the stroke the redoFn was created for. If we do not take care of this, the following doFn: let doFn = () => strokes.push(currentStroke) is going to grab the currentStroke from the surrounding scope (whatever its value is) and append it to the strokes array. The currentStroke at that time may be just empty. To avoid this behavior, we want our doFn to use a cloned copy of the currentStroke - current at time of definition of doFn, and we want it to do so always. If your undoable action is some kind of delete (“pop”) you want the reverse for your undoFn - the undo function must push the deleted object back into the array, and not mutate it in any way. To create a deep copy of our currentStroke, modern JS offers us a feature called structuredClone(). We can use the ... rest parameters to package any arguments into one array, which we will then clone: push(doFn, undoFn, ...withArgumentsToClone) { const clonedArgs = structuredClone(withArgumentsToClone); const action = { doWithData() { doFn(...clonedArgs); }, undoWithData() { undoFn(...clonedArgs); }, }; action.doWithData(); // Adding a new action wipes the redoable steps past.push(action); future.length = 0; } and we’ll amend our functions accordingly. Instead of closuring over currentStroke we’ll make it an argument: let appendStroke = strokes.push.bind(strokes); undoStack.push(appendStroke, () => strokes.pop(), currentStroke); with the push() of our undoStack taking care of making a deep clone for us. Nice! The complete definition then becomes: function createUndoStack() { const past = []; const future = []; return { push(doFn, undoFn, ...withArgumentsToClone) { const clonedArgs = structuredClone(withArgumentsToClone); const action = { doWithData() { doFn(...clonedArgs); }, undoWithData() { undoFn(...clonedArgs); }, }; action.doWithData(); // Adding a new action wipes the redoable steps past.push(action); future.length = 0; }, undo() { let action = past.pop(); if (action) { action.undoWithData(); future.unshift(action); } }, redo() { let action = future.shift(); if (action) { action.doWithData(); past.push(action); } }, get undoAvailable() { return past.length > 0; }, get redoAvailable() { return future.length > 0; }, clear() { past.length = 0; future.length = 0; return true; } } } export {createUndoStack}; Robust, small, and no indexing errors. My jam.

I have been using the #Moodle #STACK #maths related question intensely over the last few months. I had idly thought that it would be good to have an automated way of giving inputs and prts “sensible names”, i.e. instead of ans1, ans2 etc I could rename the input fields with things like width, area and have all references updated appropriately.

It turns out that the feature already exists under the menu Tidy inputs and PRT’s, wonderful!

Your exploit dev training journey starts right here!

Corelan’s “Expert-Level Stack” exploit dev course for Windows 11 delivers unmatched depth, quality, and hands-on experience.

What our students say on the #Corelan Stack course:

🗣️ “Peter will refute about every single thing you might have learned so far related to the topic in other courses… and then teach you it the right way from the ground up”

See for yourself: 👉🏼👉🏼👉🏼 bit.ly/corelan-training

🌘 Stack Overflow 上 Python 問題趨勢的變化預測
➤ Python 在 Stack Overflow 上的成長與趨勢預測分析
win-vector.com/2025/03/14/chan
最新的 Python 問題趨勢預測圖表揭示了過去與未來的變化,包含了對 2017 年底預測的各種模型比較。
+ 讓人對 Python 的未來前景有了更深入的瞭解,感覺很具啟發性。
+ 預測分析的結果對於實際應用有很大的參考價值,令人期待未來趨勢的發展。
#Python #Stack Overflow #趨勢預測

Win Vector LLC · Changing Forecasts for Python Questions on Stack OverflowI recently conducted a small time series workshop session for AI+ training hosted by ODSC. It went really well, and I’d be happy to offer longer interactive workshops going forward (please re…

#Maths #Education with the #Moodle #STACK Question Type

You can book your spot to attend the seminar on 1st April 2025 here
moodle.academy/calendar/view.p

The STACK question type is the most powerful and flexible maths related question available for any platform. With that power comes some complexity and this webinar I will address how it can be used by non experts. We will be showing ways of simplifying the question editing process and sharing resources.

moodle.academyMoodle Academy: Calendar: Day view: Tuesday, 1 April 2025 | Moodle Academy