Abstract Wikipedia/Updates/2021-08-13

From Meta, a Wikimedia project coordination wiki
Abstract Wikipedia Updates Translate

Abstract Wikipedia via mailing list Abstract Wikipedia on IRC Wikifunctions on Telegram Wikifunctions on Mastodon Wikifunctions on Twitter Wikifunctions on Facebook Wikifunctions on YouTube Wikifunctions website Translate

Testers and Wikimania

The team has been busy developing features and designing interfaces for Wikifunctions, and we are moving towards closing the current phase of the development. Aliases are now available in the data model, the data model for testers has been updated, error objects have been considerably reworked, the evaluation model can now deal with recursive calls and lazy evaluation, new built-in functions for string and boolean equality have landed, and more. It is exciting to see the pieces coming together.

In today’s weekly, we want to take a look at Testers and their current implementation. Lindsay has created a screencast that you can watch (it is without sound), and here we will describe what is happening in the video.

We start with creating a new function definition, “reverse string”, which takes a single string as an input and returns a string. On saving (0:19), the function is created and assigned Z10000. Now we edit the newly created function, and we create a first tester inline. We give it the name “test -> tset”, and set the argument to “test” and then use the “String equality” function to compare it to the expected result, “tset” (0:45).

“String equality” is a built-in function (Z866 on a fresh Wikilambda installation) that takes two strings as the arguments and returns True if they are the same, and False otherwise.

Note that even though we have created the Tester inline, in the background a new page was created (entirely behind the scenes it was assigned ZID Z10001) that holds the test.

Next, we create a test for the input “racecar”, which is a palindrome, using the same built-in function (1:00), and a test reversing “banana” and getting the output “wrong” (which is an example for a bad test) (1:19).

Next we create an implementation for “reverse string” in JavaScript. At the bottom of the page we already see our three testers working, showing that they all fail initially (1:30). Now we start implementing the function, and we enter “return Z10000K1” - and without even saving, the testers are run against our implementation and we can see that the “racecar” test passes! (It passes because it is a palindrome, and returning the input unchanged happens to be a correct implementation for palindromes). The other two tests keep failing, though (1:41).

We complete the implementation by taking the input, splitting it into an array of strings, reversing that array, and then joining the strings of the array again into a single string. Now the first test, “test -> tset” also passes, but the “banana” test (due to being actually a faulty test) continues to fail (1:54).

We save the implementation, go to the function page, and add the implementation to the function. On the function page, just like on the implementation page, we see the status of all the testers for the implementation.

Next we create a second implementation, this time in Python. Again, we start with an implementation that simply returns the input, and again it passes for “racecar”. We go back to the function page, and connect the new Python implementation with the function. On the bottom of the page we now see, in a table, the implementations against all the testers, and whether the individual testers pass or fail for each implementation (2:28).

We create another two tests, “another -> rehtona” and “final test -> tset lanif”, again inline. The tests become immediately visible upon creation. We still need to save the whole page in order to store the association with the function page. We can see how both tests pass for the JavaScript implementation and fail for the Python implementation (3:43).

Let’s go fix the Python implementation. We go to the implementation page and edit it by adding “[::-1]” to the string. That’s some Python magic - feel free to skip this paragraph explaining this syntax: Python has a few very convenient short-hand syntaxes for specific operations which, in many other languages, require functions or more complex constructs. What is happening here is that by appending the square brackets to a string variable, we treat the string implicitly as a list. Inside the square brackets we have three arguments, separated by colons (:). The first argument says at which element to start, the second argument at which element to stop, and the third argument gives the step size (say, you only want every second element of the list, you would state the step size as 2). Here, the step is -1, which means you want to walk backwards through the list. And since the first and second argument are omitted, default values are used - and the default for a negative step size is from the end to the beginning. In short, you can read this as “go through the string, backwards one by one, from the beginning to the end, and return the new resulting string”. You can find a more detailed explanation of Python’s slice notation on StackOverflow.

Once we fixed our Python code (4:07), all but one of the tests satisfyingly switched to green. We confidently store the new improved version. When we go to the function page of “reverse string”, we can see that now both the JavaScript and the Python implementation behave consistently. Time to fix the banana tester!

We go to the page for the banana tester and change the expected value from “wrong” to “ananab”. Again, before even saving, the testers are re-run against both implementations and switch from messaging failure to letting you know they passed (4:26). Going back to the function page, we can now see that all testers pass all implementations.

Finally, we see a feature added (and recorded, which explains the slightly different format) a bit later, where a new test is being created inline (4:39). While we are creating the new tester inline the result of the test runs for all implementations is already shown - before the tester is even stored yet. Once we can see both implementations pass, the new tester is saved (and thus created, 5:28), and then we save the function page itself, associating the function with the new tester (5:35).

I hope you enjoyed this whirlwind tour through our new tester features, and it gives you a small glimpse of how Wikifunctions will be working. Feedback and ideas are welcome, as always.


We are all excited about the weekend: Wikimania 2021 has started! Wikifunctions and Abstract Wikipedia will host a session on Saturday, 14 August, at 17:00 UTC, where we will have a panel to present our work and talk with you and the Wikimedia communities. Please join us, bring your questions, and we are very much looking forward to a lively discussion!