From ddb85099e27bc745273edd5340cc79d04ea2fcc6 Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:24:35 -0500 Subject: [PATCH 01/10] Classes: Add getters,setters, rename deconstructor->destructor (and update all langs to reflect it) --- web/thesauruses/_meta/classes.json | 8 +++++--- web/thesauruses/ada/2012/classes.json | 2 +- web/thesauruses/bash/3/classes.json | 2 +- web/thesauruses/bash/5/classes.json | 2 +- web/thesauruses/c/17/classes.json | 2 +- web/thesauruses/cpp/C++17/classes.json | 2 +- web/thesauruses/cpp/C++20/classes.json | 2 +- web/thesauruses/csharp/9/classes.json | 2 +- web/thesauruses/haskell/2010/classes.json | 2 +- web/thesauruses/java/11/classes.json | 2 +- web/thesauruses/java/15/classes.json | 2 +- web/thesauruses/java/17/classes.json | 2 +- web/thesauruses/javascript/ECMAScript 2009/classes.json | 2 +- web/thesauruses/javascript/ECMAScript 2020/classes.json | 2 +- web/thesauruses/javascript/ECMAScript 2021/classes.json | 2 +- web/thesauruses/javascript/ECMAScript 2023/classes.json | 2 +- web/thesauruses/kotlin/1.5/classes.json | 2 +- web/thesauruses/php/7/classes.json | 2 +- web/thesauruses/php/8/classes.json | 2 +- web/thesauruses/powershell/7/classes.json | 2 +- web/thesauruses/python/3/classes.json | 2 +- web/thesauruses/r/4/classes.json | 2 +- web/thesauruses/swift/5/classes.json | 2 +- web/thesauruses/typescript/4/classes.json | 2 +- web/thesauruses/vbnet/16/classes.json | 2 +- 25 files changed, 29 insertions(+), 27 deletions(-) diff --git a/web/thesauruses/_meta/classes.json b/web/thesauruses/_meta/classes.json index 53b7ec39e..3b2bd6562 100644 --- a/web/thesauruses/_meta/classes.json +++ b/web/thesauruses/_meta/classes.json @@ -22,7 +22,9 @@ "private_functions": "Defining private functions", "protected_functions": "Defining protected functions", "public_functions": "Defining public functions", - "static_functions": "Defining static functions" + "static_functions": "Defining static functions", + "getter": "Defining a getter for a property", + "setter": "Defining a setter for a property" }, "Extending and Implementing Classes": { "extends_class": "Class that inherits/extends another class", @@ -34,9 +36,9 @@ "instantiating_object": "Instantiating a new object", "instantiating_polymorphic_object": "Instantiating a polymorphic object" }, - "Constructors and Deconstructor": { + "Constructors and Destructor/Deconstructor": { "implement_constructor": "Implementing a class constructor", - "implement_deconstructor": "Implementing a class deconstructor" + "implement_destructor": "Implementing a class destructor/deconstructor" } } } diff --git a/web/thesauruses/ada/2012/classes.json b/web/thesauruses/ada/2012/classes.json index 57ef0698c..d960f25ea 100644 --- a/web/thesauruses/ada/2012/classes.json +++ b/web/thesauruses/ada/2012/classes.json @@ -139,7 +139,7 @@ "not-implemented": true, "comment": "A constructor is simply a method with the class as an output parameter" }, - "implement_deconstructor": { + "implement_destructor": { "name": "Implementing a class deconstructor", "not-implemented": true } diff --git a/web/thesauruses/bash/3/classes.json b/web/thesauruses/bash/3/classes.json index bb12802d1..a78876fe8 100644 --- a/web/thesauruses/bash/3/classes.json +++ b/web/thesauruses/bash/3/classes.json @@ -98,7 +98,7 @@ "not-implemented": true, "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": true, "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/bash/5/classes.json b/web/thesauruses/bash/5/classes.json index e307d5b55..cfaa7d01e 100644 --- a/web/thesauruses/bash/5/classes.json +++ b/web/thesauruses/bash/5/classes.json @@ -98,7 +98,7 @@ "not-implemented": true, "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": true, "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/c/17/classes.json b/web/thesauruses/c/17/classes.json index a719ec6a2..678eaa1d0 100644 --- a/web/thesauruses/c/17/classes.json +++ b/web/thesauruses/c/17/classes.json @@ -98,7 +98,7 @@ "not-implemented": "true", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": "true", "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/cpp/C++17/classes.json b/web/thesauruses/cpp/C++17/classes.json index 09039c060..aed6c06f8 100644 --- a/web/thesauruses/cpp/C++17/classes.json +++ b/web/thesauruses/cpp/C++17/classes.json @@ -101,7 +101,7 @@ "code": "class ClassName {\n public: ClassName(){\n //constructor body \n} \n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "code": " class ClassName {\n public: ~ClassName(){\n //deconstructor body \n} \n}", "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/cpp/C++20/classes.json b/web/thesauruses/cpp/C++20/classes.json index 24711d47e..2831ebb52 100644 --- a/web/thesauruses/cpp/C++20/classes.json +++ b/web/thesauruses/cpp/C++20/classes.json @@ -101,7 +101,7 @@ "code": "class ClassName {\n public: ClassName(){\n //constructor body \n} \n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "code": " class ClassName {\n public: ~ClassName(){\n //deconstructor body \n} \n}", "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/csharp/9/classes.json b/web/thesauruses/csharp/9/classes.json index 427027de7..87b8b8055 100644 --- a/web/thesauruses/csharp/9/classes.json +++ b/web/thesauruses/csharp/9/classes.json @@ -99,7 +99,7 @@ "code": "class ClassName {\n\tconstructor ClassName() {\n\t}\n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "code": "class ClassName {\n\t-ClassName() {\n\t}\n}", "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/haskell/2010/classes.json b/web/thesauruses/haskell/2010/classes.json index 42d21ad79..8490f4994 100644 --- a/web/thesauruses/haskell/2010/classes.json +++ b/web/thesauruses/haskell/2010/classes.json @@ -119,7 +119,7 @@ "not-implemented": true, "comment": "You specify all constructors when defining the type, they are simple containers for all members" }, - "implement_deconstructor": { + "implement_destructor": { "name": "Implementing a class deconstructor", "not-implemented": true } diff --git a/web/thesauruses/java/11/classes.json b/web/thesauruses/java/11/classes.json index 8d2c07645..1694898be 100644 --- a/web/thesauruses/java/11/classes.json +++ b/web/thesauruses/java/11/classes.json @@ -104,7 +104,7 @@ "code": "access-modifier class ClassName {\n ClassName(){\n //constructor body \n} \n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": "true", "comment": "There is no concept of destructor in Java. In place of the destructor, Java provides the garbage collector that works the same as the destructor. The garbage collector is a program (thread) that runs on the JVM. It automatically deletes the unused objects (objects that are no longer used) and free-up the memory.", "name": "Implementing a class deconstructor" diff --git a/web/thesauruses/java/15/classes.json b/web/thesauruses/java/15/classes.json index 34bfefa1f..302e2fba4 100644 --- a/web/thesauruses/java/15/classes.json +++ b/web/thesauruses/java/15/classes.json @@ -104,7 +104,7 @@ "code": "access-modifier class ClassName {\n ClassName(){\n //constructor body \n} \n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": "true", "comment": "There is no concept of destructor in Java. In place of the destructor, Java provides the garbage collector that works the same as the destructor. The garbage collector is a program (thread) that runs on the JVM. It automatically deletes the unused objects (objects that are no longer used) and free-up the memory.", "name": "Implementing a class deconstructor" diff --git a/web/thesauruses/java/17/classes.json b/web/thesauruses/java/17/classes.json index 3f85196ec..95f739626 100644 --- a/web/thesauruses/java/17/classes.json +++ b/web/thesauruses/java/17/classes.json @@ -104,7 +104,7 @@ "code": "access-modifier class ClassName {\n ClassName(){\n //constructor body \n} \n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": "true", "comment": "There is no concept of destructor in Java. In place of the destructor, Java provides the garbage collector that works the same as the destructor. The garbage collector is a program (thread) that runs on the JVM. It automatically deletes the unused objects (objects that are no longer used) and free-up the memory.", "name": "Implementing a class deconstructor" diff --git a/web/thesauruses/javascript/ECMAScript 2009/classes.json b/web/thesauruses/javascript/ECMAScript 2009/classes.json index 035ed3ad2..44f48d7a6 100644 --- a/web/thesauruses/javascript/ECMAScript 2009/classes.json +++ b/web/thesauruses/javascript/ECMAScript 2009/classes.json @@ -100,7 +100,7 @@ "code": "function ClassName() {\n // Constructor body\n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": true, "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/javascript/ECMAScript 2020/classes.json b/web/thesauruses/javascript/ECMAScript 2020/classes.json index 9557632f1..f9c3da132 100644 --- a/web/thesauruses/javascript/ECMAScript 2020/classes.json +++ b/web/thesauruses/javascript/ECMAScript 2020/classes.json @@ -105,7 +105,7 @@ "code": "class ClassName {\n constructor() {\n // Constructor body\n }\n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": true, "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/javascript/ECMAScript 2021/classes.json b/web/thesauruses/javascript/ECMAScript 2021/classes.json index 1a40612ad..15dadd848 100644 --- a/web/thesauruses/javascript/ECMAScript 2021/classes.json +++ b/web/thesauruses/javascript/ECMAScript 2021/classes.json @@ -100,7 +100,7 @@ "code": "class ClassName {\n constructor() {\n // Constructor body\n }\n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": true, "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/javascript/ECMAScript 2023/classes.json b/web/thesauruses/javascript/ECMAScript 2023/classes.json index a09af94d7..5a5d65197 100644 --- a/web/thesauruses/javascript/ECMAScript 2023/classes.json +++ b/web/thesauruses/javascript/ECMAScript 2023/classes.json @@ -99,7 +99,7 @@ "code": "class ClassName {\n constructor() {\n // Constructor body\n }\n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": true, "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/kotlin/1.5/classes.json b/web/thesauruses/kotlin/1.5/classes.json index 4866358e4..28bf9913f 100644 --- a/web/thesauruses/kotlin/1.5/classes.json +++ b/web/thesauruses/kotlin/1.5/classes.json @@ -99,7 +99,7 @@ "code": "class ClassName(val property: Type) {\n init {\n // Constructor body\n }\n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": true, "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/php/7/classes.json b/web/thesauruses/php/7/classes.json index d75e693ae..5bf4718e3 100644 --- a/web/thesauruses/php/7/classes.json +++ b/web/thesauruses/php/7/classes.json @@ -105,7 +105,7 @@ "code": "public function __construct() {\n //Method body \n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "code": "public function __destruct() {\n //Method body \n}", "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/php/8/classes.json b/web/thesauruses/php/8/classes.json index 6b53698a6..4b8c0d8d8 100644 --- a/web/thesauruses/php/8/classes.json +++ b/web/thesauruses/php/8/classes.json @@ -105,7 +105,7 @@ "code": "public function __construct() {\n //Method body \n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "code": "public function __destruct() {\n //Method body \n}", "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/powershell/7/classes.json b/web/thesauruses/powershell/7/classes.json index 5ee3121ae..8bcc3c359 100644 --- a/web/thesauruses/powershell/7/classes.json +++ b/web/thesauruses/powershell/7/classes.json @@ -149,7 +149,7 @@ "}" ] }, - "implement_deconstructor": { + "implement_destructor": { "name": "Implementing a class deconstructor", "not-implemented": true } diff --git a/web/thesauruses/python/3/classes.json b/web/thesauruses/python/3/classes.json index 7464dd491..17267a504 100644 --- a/web/thesauruses/python/3/classes.json +++ b/web/thesauruses/python/3/classes.json @@ -108,7 +108,7 @@ "code": "def __init__(self):\n # body of the constructor", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "code": "def __del__(self):\n # body of destructor", "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/r/4/classes.json b/web/thesauruses/r/4/classes.json index 764355bb5..356790f1e 100644 --- a/web/thesauruses/r/4/classes.json +++ b/web/thesauruses/r/4/classes.json @@ -126,7 +126,7 @@ "name": "Implementing a class constructor", "not-implemented":true }, - "implement_deconstructor": { + "implement_destructor": { "name": "Implementing a class deconstructor", "not-implemented":true } diff --git a/web/thesauruses/swift/5/classes.json b/web/thesauruses/swift/5/classes.json index 072f41b98..16e356756 100644 --- a/web/thesauruses/swift/5/classes.json +++ b/web/thesauruses/swift/5/classes.json @@ -101,7 +101,7 @@ "code": "class Class_Name {\n init () {\n} \n}", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "code": "class Class_Name {\n deinit () {\n} \n}", "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/typescript/4/classes.json b/web/thesauruses/typescript/4/classes.json index fc39f2095..39a43053e 100644 --- a/web/thesauruses/typescript/4/classes.json +++ b/web/thesauruses/typescript/4/classes.json @@ -98,7 +98,7 @@ "code": "class Employee {\n empCode: number;\n empName: string;\n constructor(code: number, name: string) {\n this.empName = name;\n this.empCode = code;\n }\n }", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "not-implemented": true, "name": "Implementing a class deconstructor" } diff --git a/web/thesauruses/vbnet/16/classes.json b/web/thesauruses/vbnet/16/classes.json index 36a56cfcd..3f09d773c 100644 --- a/web/thesauruses/vbnet/16/classes.json +++ b/web/thesauruses/vbnet/16/classes.json @@ -99,7 +99,7 @@ "code": "Class ClassName \n\tSub New() \n\tEnd Sub\nEnd Class", "name": "Implementing a class constructor" }, - "implement_deconstructor": { + "implement_destructor": { "code": "Class ClassName \n\tSub Finalize()\n\tEnd Sub\nEnd Class", "name": "Implementing a class deconstructor" } From 7dae6ef6b7125740b5275b9fbdabb47e0431bf0f Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:25:27 -0500 Subject: [PATCH 02/10] Data Types: add special types (like null/optional/void/etc.) --- web/thesauruses/_meta/data_types.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/web/thesauruses/_meta/data_types.json b/web/thesauruses/_meta/data_types.json index 9239653dc..50220123a 100644 --- a/web/thesauruses/_meta/data_types.json +++ b/web/thesauruses/_meta/data_types.json @@ -34,6 +34,13 @@ "complex_as_object": "Complex Number as an object", "real_number_part": "Complex number real part", "imaginary_number_part": "Complex number imaginary part" + }, + "Special Types": { + "null_type": "Null / None / Nil", + "optional_type": "Optional / Maybe / Nullable", + "void_type": "Void / Unit / None", + "enum_type": "Enumeration (Enum)", + "tuple_type": "Tuple" } } } From 5d1f69b1610b6c4b4646f4c47c8489e79866499e Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:27:08 -0500 Subject: [PATCH 03/10] IO: Add environment variables, clear console, read dir info, move dir, meta data --- web/thesauruses/_meta/io.json | 29 ++++++-- web/thesauruses/c/17/io.json | 2 +- .../javascript/ECMAScript 2023/io.json | 74 +++++++++++++++++++ 3 files changed, 98 insertions(+), 7 deletions(-) diff --git a/web/thesauruses/_meta/io.json b/web/thesauruses/_meta/io.json index 78f6097ed..764f337c4 100644 --- a/web/thesauruses/_meta/io.json +++ b/web/thesauruses/_meta/io.json @@ -1,8 +1,7 @@ { "meta": { - "language": "language_key", - "language_version": "version.number", - "language_name": "Human-Friendly Language Name" + "structure": "io", + "structure_name": "Input and Output" }, "categories": { "Console IO": { @@ -10,18 +9,18 @@ "write_line_with_new_line": "Write a line to the console with a return character", "read_line": "Read a line of user input from the console", "read_char": "Read a single char of user input from the console", - "clear_console_cutput": "Clear the console output", + "clear_console_output": "Clear the console output", "change_console_background_color": "Change the background color of the console", "change_console_text_color": "Change the text color of the console" }, "File IO": { "file_functions_lib": "Library containing file IO functions", "list_directory": "List of the items in the current directory", - "read_directory_info": "Get infomation about the current directory (number of items, size, etc)", + "read_directory_info": "Get information about the current directory (number of items, size, etc)", "create_directory": "Create a directory", "delete_directory": "Delete a directory", "rename_directory": "Rename a directory", - "move_directory": "Move a directory to another locaiton", + "move_directory": "Move a directory to another location", "update_directory_permissions": "Update the permissions a user, group, or application has to a directory", "read_line_of_file": "Read a single line from a file", "read_lines_of_file": "Read all the lines in a file", @@ -31,6 +30,24 @@ "update_file": "Update a file", "move_file": "Move a file to a new location" }, + "File and Directory Metadata": { + "check_file_exists": "Check if a file exists", + "check_directory_exists": "Check if a directory exists", + "get_file_size": "Get the size of a file", + "get_file_last_modified": "Get the last modified time of a file", + "is_file": "Check if a path is a file", + "is_directory": "Check if a path is a directory", + "get_absolute_path": "Get the absolute path of a file/directory" + }, + "Environment Variables": { + "get_environment_variable": "Get an environment variable", + "set_environment_variable": "Set an environment variable", + "list_all_environment_variables": "List all environment variables" + }, + "Temporary Files and Directories": { + "create_temporary_file": "Create a temporary file", + "create_temporary_directory": "Create a temporary directory" + }, "Network IO": { "network_functions_lib": "Library containing network IO functions", "send_a_http_request": "Send a HTTP request", diff --git a/web/thesauruses/c/17/io.json b/web/thesauruses/c/17/io.json index 5a92fe15b..22345653a 100644 --- a/web/thesauruses/c/17/io.json +++ b/web/thesauruses/c/17/io.json @@ -23,7 +23,7 @@ "code": "getchar()", "name": "Read a single char of user input from the console" }, - "clear_console_cutput": { + "clear_console_output": { "not-implemented":"true", "comment": "system() is defined in stdlib.h which invokes a system call", "name": "Clear the console output" diff --git a/web/thesauruses/javascript/ECMAScript 2023/io.json b/web/thesauruses/javascript/ECMAScript 2023/io.json index 64e6d8a72..38c13c391 100644 --- a/web/thesauruses/javascript/ECMAScript 2023/io.json +++ b/web/thesauruses/javascript/ECMAScript 2023/io.json @@ -145,6 +145,80 @@ "code": "fs.renameSync(old_location, new_location);", "comment": "The `fs` module is a part of Node.js and is not available in the browser." }, + "check_file_exists": { + "name": "Check if a file exists", + "code": "fs.existsSync(location);", + "comment": "The `fs` module is a part of Node.js and is not available in the browser." + }, + "check_directory_exists": { + "name": "Check if a directory exists", + "code": "fs.existsSync(location);", + "comment": "The `fs` module is a part of Node.js and is not available in the browser." + }, + "get_file_size": { + "name": "Get the size of a file", + "code": "fs.statSync(location).size;", + "comment": "The `fs` module is a part of Node.js and is not available in the browser." + }, + "get_file_last_modified": { + "name": "Get the last modified time of a file", + "code": "fs.statSync(location).mtime;", + "comment": "The `fs` module is a part of Node.js and is not available in the browser." + }, + "is_file": { + "name": "Check if a path is a file", + "code": "fs.statSync(location).isFile();", + "comment": "The `fs` module is a part of Node.js and is not available in the browser." + }, + "is_directory": { + "name": "Check if a path is a directory", + "code": "fs.statSync(location).isDirectory();", + "comment": "The `fs` module is a part of Node.js and is not available in the browser." + }, + "get_absolute_path": { + "name": "Get the absolute path of a file/directory", + "code": [ + "const path = require('path');", + "path.resolve(location);" + ], + "comment": "The `path` module is a part of Node.js and is not available in the browser." + }, + "get_environment_variable": { + "name": "Get an environment variable", + "code": "process.env.VARIABLE_NAME;", + "comment": "`process.env` is Node.js specific." + }, + "set_environment_variable": { + "name": "Set an environment variable", + "code": "process.env.VARIABLE_NAME = 'value';", + "comment": "`process.env` is Node.js specific." + }, + "list_all_environment_variables": { + "name": "List all environment variables", + "code": "process.env;", + "comment": "`process.env` is Node.js specific." + }, + "create_temporary_file": { + "name": "Create a temporary file", + "code": [ + "const os = require('os');", + "const path = require('path');", + "const fs = require('fs');", + "const tempFilePath = path.join(os.tmpdir(), 'temp-file');", + "fs.writeFileSync(tempFilePath, content);" + ], + "comment": "`os`, `path`, and `fs` modules are part of Node.js." + }, + "create_temporary_directory": { + "name": "Create a temporary directory", + "code": [ + "const os = require('os');", + "const fs = require('fs');", + "const path = require('path');", + "const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'temp-'));" + ], + "comment": "`os`, `path`, and `fs` modules are part of Node.js." + }, "network_functions_lib": { "name": "Library containing network IO functions", "code": [ From d16adb0188de1f1b5927cc5ed70f7657442f3935 Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:28:20 -0500 Subject: [PATCH 04/10] Lists: Clear find/contains up, add is empty/resize/clear, slice, get first, get last, remove dupes, flatten --- web/thesauruses/_meta/lists.json | 14 ++++- web/thesauruses/ada/2012/lists.json | 10 +++- web/thesauruses/csharp/9/lists.json | 10 +++- web/thesauruses/go/1/lists.json | 13 +++-- web/thesauruses/haskell/2010/lists.json | 8 ++- web/thesauruses/java/11/lists.json | 11 ++-- web/thesauruses/java/15/lists.json | 11 ++-- web/thesauruses/java/17/lists.json | 11 ++-- .../javascript/ECMAScript 2009/lists.json | 11 ++-- .../javascript/ECMAScript 2020/lists.json | 15 +++-- .../javascript/ECMAScript 2021/lists.json | 15 +++-- .../javascript/ECMAScript 2023/lists.json | 42 ++++++++++++-- web/thesauruses/kotlin/1.5/lists.json | 11 ++-- web/thesauruses/nim/1/lists.json | 8 ++- web/thesauruses/objectivec/2/lists.json | 10 +++- web/thesauruses/php/7/lists.json | 8 ++- web/thesauruses/php/8/lists.json | 8 ++- web/thesauruses/python/3/lists.json | 58 +++++++++++++++++-- web/thesauruses/r/4/lists.json | 12 ++-- web/thesauruses/ruby/3/lists.json | 18 +++--- web/thesauruses/swift/5/lists.json | 10 +++- web/thesauruses/typescript/4/lists.json | 10 +++- web/thesauruses/vbnet/16/lists.json | 10 +++- 23 files changed, 249 insertions(+), 85 deletions(-) diff --git a/web/thesauruses/_meta/lists.json b/web/thesauruses/_meta/lists.json index 934f020d7..a072ff1e1 100644 --- a/web/thesauruses/_meta/lists.json +++ b/web/thesauruses/_meta/lists.json @@ -95,9 +95,10 @@ "delete_immutable_set": "Delete the set" }, "Find/Search Functions": { - "find_element_by_value": "Find/search for an element by value", + "get_index_of_element": "Get the index of an element by value", "find_minimum_element": "Find the minimum value in a list", "find_maximum_element": "Find the maximum value in a list", + "contains_element": "Check if the list contains a specific element", "convert_list_to_string": "Convert a list to a string" }, "Splitting/Joining Lists": { @@ -111,7 +112,9 @@ }, "Sizing/Resizing Lists": { "get_list_length": "Get list length", - "resize_list": "Increase/decrease list size" + "is_list_empty": "Check if the list is empty", + "resize_list": "Increase/decrease list size", + "clear_list": "Remove all elements from the list" }, "Comparing/Equality": { "do_two_lists_match_exactly": "Do two lists match every element?", @@ -129,6 +132,13 @@ "filter": "Filter a list based on criteria", "reduce_left": "Reduce a list left-to-right", "reduce_right": "Reduce a list right-to-left" + }, + "Advanced Collection Operations": { + "slice_list": "Get a slice/portion of a list (view or shallow copy)", + "get_first_element": "Get the first element", + "get_last_element": "Get the last element", + "remove_duplicates": "Remove duplicate elements from the list", + "flatten_list": "Flatten a nested list" } } } diff --git a/web/thesauruses/ada/2012/lists.json b/web/thesauruses/ada/2012/lists.json index b97a908d5..e18efe18f 100644 --- a/web/thesauruses/ada/2012/lists.json +++ b/web/thesauruses/ada/2012/lists.json @@ -234,9 +234,9 @@ "find_element_at_position": { "code": "V(index)" }, - "find_element_by_value": { - "code": "V.Find_Index (value) \n V.Find (value)", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "V.Find_Index (value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "not-implemented": "true", @@ -246,6 +246,10 @@ "not-implemented": "true", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "V.Contains (value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "not-implemented": "true", "name": "Convert a list to a string" diff --git a/web/thesauruses/csharp/9/lists.json b/web/thesauruses/csharp/9/lists.json index e3fb3b0f8..34d310fda 100644 --- a/web/thesauruses/csharp/9/lists.json +++ b/web/thesauruses/csharp/9/lists.json @@ -217,9 +217,9 @@ "find_element_at_position": { "code": "listName[index]" }, - "find_element_by_value": { - "code": "listName.Find(x => x == value)", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "listName.IndexOf(value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "listName.Min()", @@ -229,6 +229,10 @@ "code": "listName.Max()", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "listName.Contains(value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "code": "string.Join(\",\",listName)", "name": "Convert a list to a string" diff --git a/web/thesauruses/go/1/lists.json b/web/thesauruses/go/1/lists.json index 57dd91d7f..dfc27abe3 100644 --- a/web/thesauruses/go/1/lists.json +++ b/web/thesauruses/go/1/lists.json @@ -228,10 +228,10 @@ "find_element_at_position": { "not-implemented": true }, - "find_element_by_value": { - "comment": "Here s is the slice (list) and value is the search query", - "code": "for _, v := range s {\n if s == value {\n return true\n }\n}\nreturn false", - "name": "Find/search for an element by value" + "get_index_of_element": { + "comment": "Go does not have a built-in indexOf function for slices. You must iterate through the slice.", + "code": "for i, v := range s {\n if v == value {\n return i\n }\n}\nreturn -1", + "name": "Get the index of an element by value" }, "find_minimum_element": { "comment": "Here s is the slice(list) and min is the minimum value", @@ -243,6 +243,11 @@ "code": "max = s[0]\nfor _, value := range s {\n if (value > max) {\n max = value\n }\n}", "name": "Find the maximum value in a list" }, + "contains_element": { + "comment": "Go does not have a built-in contains function for slices. You must iterate through the slice.", + "code": "for _, v := range s {\n if v == value {\n return true\n }\n}\nreturn false", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "comment": "Built-in \"strings\" package needs to be imported first", "code": "str := strings.Join(slice, \" \")", diff --git a/web/thesauruses/haskell/2010/lists.json b/web/thesauruses/haskell/2010/lists.json index 41e2c5c79..e7d024e23 100644 --- a/web/thesauruses/haskell/2010/lists.json +++ b/web/thesauruses/haskell/2010/lists.json @@ -224,9 +224,9 @@ "not-implemented": true, "name": "Delete the set" }, - "find_element_by_value": { + "get_index_of_element": { "code": "elemIndex elementToSearchFor list", - "name": "Find/search for an element by value" + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "minimum list", @@ -238,6 +238,10 @@ "comment": "maximum works on all `Foldables` not just lists", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "element `elem` list", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "not-implemented": true, "comment": "A `String` is just a `List` of `Char`s", diff --git a/web/thesauruses/java/11/lists.json b/web/thesauruses/java/11/lists.json index 648f4ecad..2946ff2d3 100644 --- a/web/thesauruses/java/11/lists.json +++ b/web/thesauruses/java/11/lists.json @@ -237,10 +237,9 @@ "find_element_at_position": { "not-implemented": true }, - "find_element_by_value": { - "comment": "The stream capabilities added in Java 8+ provide a generic map, filter, and reduce capability for all built-in collections.", - "code": "myList.stream().filter(v -> v == value).findFirst().get()", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "myList.indexOf(value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "myList\n .stream()\n .mapToInt(v -> v)\n .min().orElseThrow(NoSuchElementException::new);", @@ -250,6 +249,10 @@ "code": "myList\n .stream()\n .mapToInt(v -> v)\n .max().orElseThrow(NoSuchElementException::new);", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "myList.contains(value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "comment": "If the list contains non-String objects, you can use the stream capabilities to map the items to Strings first.", "code": "String.join(\", \", list)", diff --git a/web/thesauruses/java/15/lists.json b/web/thesauruses/java/15/lists.json index f9139ca02..2f7d2695a 100644 --- a/web/thesauruses/java/15/lists.json +++ b/web/thesauruses/java/15/lists.json @@ -237,10 +237,9 @@ "find_element_at_position": { "not-implemented": true }, - "find_element_by_value": { - "comment": "The stream capabilities added in Java 8+ provide a generic map, filter, and reduce capability for all built-in collections.", - "code": "myList.stream().filter(v -> v == value).findFirst().get()", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "myList.indexOf(value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "myList\n .stream()\n .mapToInt(v -> v)\n .min().orElseThrow(NoSuchElementException::new);", @@ -250,6 +249,10 @@ "code": "myList\n .stream()\n .mapToInt(v -> v)\n .max().orElseThrow(NoSuchElementException::new);", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "myList.contains(value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "comment": "If the list contains non-String objects, you can use the stream capabilities to map the items to Strings first.", "code": "String.join(\", \", list)", diff --git a/web/thesauruses/java/17/lists.json b/web/thesauruses/java/17/lists.json index 81a6c4749..650e990ab 100644 --- a/web/thesauruses/java/17/lists.json +++ b/web/thesauruses/java/17/lists.json @@ -237,10 +237,9 @@ "find_element_at_position": { "not-implemented": true }, - "find_element_by_value": { - "comment": "The stream capabilities added in Java 8+ provide a generic map, filter, and reduce capability for all built-in collections.", - "code": "myList.stream().filter(v -> v == value).findFirst().get()", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "myList.indexOf(value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "myList\n .stream()\n .mapToInt(v -> v)\n .min().orElseThrow(NoSuchElementException::new);", @@ -250,6 +249,10 @@ "code": "myList\n .stream()\n .mapToInt(v -> v)\n .max().orElseThrow(NoSuchElementException::new);", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "myList.contains(value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "comment": "If the list contains non-String objects, you can use the stream capabilities to map the items to Strings first.", "code": "String.join(\", \", list)", diff --git a/web/thesauruses/javascript/ECMAScript 2009/lists.json b/web/thesauruses/javascript/ECMAScript 2009/lists.json index 44bf5944d..310bb75a9 100644 --- a/web/thesauruses/javascript/ECMAScript 2009/lists.json +++ b/web/thesauruses/javascript/ECMAScript 2009/lists.json @@ -289,10 +289,9 @@ "not-implemented": true, "name": "Delete the set" }, - "find_element_by_value": { - "name": "Find/search for an element by value", - "code": "list_name.filter(element => element === value)", - "comment": "Works only with an array. Returns a collection of elements matching the value." + "get_index_of_element": { + "name": "Get the index of an element by value", + "code": "list_name.indexOf(value)" }, "find_minimum_element": { "name": "Find the minimum value in a list", @@ -310,6 +309,10 @@ ], "comment": "These solutions do not have the same performance depending on the browsers. Choose from the first to the last one depending on your needs." }, + "contains_element": { + "name": "Check if the list contains a specific element", + "code": "list_name.indexOf(value) !== -1" + }, "convert_list_to_string": { "name": "Convert a list to a string", "code": "list_name.join(separator)" diff --git a/web/thesauruses/javascript/ECMAScript 2020/lists.json b/web/thesauruses/javascript/ECMAScript 2020/lists.json index ed8fb5257..21b3f74b2 100644 --- a/web/thesauruses/javascript/ECMAScript 2020/lists.json +++ b/web/thesauruses/javascript/ECMAScript 2020/lists.json @@ -299,13 +299,12 @@ "not-implemented": true, "name": "Delete the set" }, - "find_element_by_value": { - "name": "Find/search for an element by value", + "get_index_of_element": { + "name": "Get the index of an element by value", "code": [ - "list_name.filter(element => element === value)", - "list_name.find(element => element === value)" - ], - "comment": "Works only with an array. The first one returns a collection of elements matching the value, and the second returns the first element." + "list_name.indexOf(value)", + "list_name.findIndex(element => element === value)" + ] }, "find_minimum_element": { "name": "Find the minimum value in a list", @@ -325,6 +324,10 @@ ], "comment": "These solutions do not have the same performance depending on the browsers. Choose from the first to the last one depending on your needs." }, + "contains_element": { + "name": "Check if the list contains a specific element", + "code": "list_name.includes(value)" + }, "convert_list_to_string": { "name": "Convert a list to a string", "code": "list_name.join(separator)" diff --git a/web/thesauruses/javascript/ECMAScript 2021/lists.json b/web/thesauruses/javascript/ECMAScript 2021/lists.json index 83d69f7dd..102d3bf84 100644 --- a/web/thesauruses/javascript/ECMAScript 2021/lists.json +++ b/web/thesauruses/javascript/ECMAScript 2021/lists.json @@ -299,13 +299,12 @@ "not-implemented": true, "name": "Delete the set" }, - "find_element_by_value": { - "name": "Find/search for an element by value", + "get_index_of_element": { + "name": "Get the index of an element by value", "code": [ - "list_name.filter(element => element === value)", - "list_name.find(element => element === value)" - ], - "comment": "Works only with an array. The first one returns a collection of elements matching the value, and the second returns the first element." + "list_name.indexOf(value)", + "list_name.findIndex(element => element === value)" + ] }, "find_minimum_element": { "name": "Find the minimum value in a list", @@ -325,6 +324,10 @@ ], "comment": "These solutions do not have the same performance depending on the browsers. Choose from the first to the last one depending on your needs." }, + "contains_element": { + "name": "Check if the list contains a specific element", + "code": "list_name.includes(value)" + }, "convert_list_to_string": { "name": "Convert a list to a string", "code": "list_name.join(separator)" diff --git a/web/thesauruses/javascript/ECMAScript 2023/lists.json b/web/thesauruses/javascript/ECMAScript 2023/lists.json index 79a788aaf..acafb33a9 100644 --- a/web/thesauruses/javascript/ECMAScript 2023/lists.json +++ b/web/thesauruses/javascript/ECMAScript 2023/lists.json @@ -303,13 +303,13 @@ "not-implemented": true, "name": "Delete the set" }, - "find_element_by_value": { - "name": "Find/search for an element by value", + "get_index_of_element": { + "name": "Get the index of an element by value", "code": [ - "list_name.filter(element => element === value)", - "list_name.find(element => element === value)" + "list_name.indexOf(value)", + "list_name.findIndex(element => element === value)" ], - "comment": "Works only with an array. The first one returns a collection of elements matching the value, and the second returns the first element." + "comment": "indexOf works for primitive values, while findIndex allows for more complex search criteria." }, "find_minimum_element": { "name": "Find the minimum value in a list", @@ -329,6 +329,10 @@ ], "comment": "These solutions do not have the same performance depending on the browsers. Choose from the first to the last one depending on your needs." }, + "contains_element": { + "name": "Check if the list contains a specific element", + "code": "list_name.includes(value)" + }, "convert_list_to_string": { "name": "Convert a list to a string", "code": "list_name.join(separator)" @@ -372,10 +376,18 @@ "name": "Get list length", "code": "list_name.length" }, + "is_list_empty": { + "name": "Check if the list is empty", + "code": "list_name.length === 0" + }, "resize_list": { "name": "Increase/decrease list size", "code": "list_name.length = size" }, + "clear_list": { + "name": "Remove all elements from the list", + "code": "list_name.length = 0" + }, "do_two_lists_match_exactly": { "name": "Do two lists match every element?", "code": [ @@ -433,6 +445,26 @@ "reduce_right": { "name": "Reduce a list right-to-left", "code": "list_name.reduceRight((accumulator, value) => { /* Function body */ })" + }, + "slice_list": { + "name": "Get a slice/portion of a list (view or shallow copy)", + "code": "list_name.slice(start, end)" + }, + "get_first_element": { + "name": "Get the first element", + "code": "list_name[0]" + }, + "get_last_element": { + "name": "Get the last element", + "code": "list_name[list_name.length - 1]" + }, + "remove_duplicates": { + "name": "Remove duplicate elements from the list", + "code": "[...new Set(list_name)]" + }, + "flatten_list": { + "name": "Flatten a nested list", + "code": "list_name.flat()" } } } \ No newline at end of file diff --git a/web/thesauruses/kotlin/1.5/lists.json b/web/thesauruses/kotlin/1.5/lists.json index 378dedaf1..9b146e99d 100644 --- a/web/thesauruses/kotlin/1.5/lists.json +++ b/web/thesauruses/kotlin/1.5/lists.json @@ -219,10 +219,9 @@ "not-implemented": true, "name": "Find/search for an element by position" }, - "find_element_by_value": { - "comment": "Finds the first matching element by value.", - "code": "myList.find { it == value }", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "myList.indexOf(value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "myList.minOrNull() ?: throw NoSuchElementException()", @@ -232,6 +231,10 @@ "code": "myList.maxOrNull() ?: throw NoSuchElementException()", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "myList.contains(value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "comment": "Converts list elements to a string representation.", "code": "myList.joinToString(\", \")", diff --git a/web/thesauruses/nim/1/lists.json b/web/thesauruses/nim/1/lists.json index 49c9b02f6..59fb03673 100644 --- a/web/thesauruses/nim/1/lists.json +++ b/web/thesauruses/nim/1/lists.json @@ -174,8 +174,8 @@ "name": "Delete the set", "code": "Automatic compile-time deterministic memory management" }, - "find_element_by_value": { - "name": "Find/search for an element by value", + "get_index_of_element": { + "name": "Get the index of an element by value", "code": "list.find item" }, "find_minimum_element": { @@ -186,6 +186,10 @@ "name": "Find the maximum value in a list", "code": "list.high" }, + "contains_element": { + "name": "Check if the list contains a specific element", + "code": "item in list" + }, "convert_list_to_string": { "name": "Convert a list to a string", "code": "$list" diff --git a/web/thesauruses/objectivec/2/lists.json b/web/thesauruses/objectivec/2/lists.json index 384ececc9..5f8878a00 100644 --- a/web/thesauruses/objectivec/2/lists.json +++ b/web/thesauruses/objectivec/2/lists.json @@ -233,9 +233,9 @@ "find_element_at_position": { "code": "indexOfObjectIdenticalTo:" }, - "find_element_by_value": { - "code": "containsObject:", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "[myArray indexOfObject:@\"value\"]", + "name": "Get the index of an element by value" }, "find_minimum_element": { "not-implemented": "true", @@ -245,6 +245,10 @@ "not-implemented": "true", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "[myArray containsObject:@\"value\"]", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "code": "NSString * result = [[array valueForKey:@\"description\"] componentsJoinedByString:@\"\"];", "name": "Convert a list to a string" diff --git a/web/thesauruses/php/7/lists.json b/web/thesauruses/php/7/lists.json index 61524b957..0f437c254 100644 --- a/web/thesauruses/php/7/lists.json +++ b/web/thesauruses/php/7/lists.json @@ -270,9 +270,9 @@ "find_element_at_position": { "code": "$array[$n]" }, - "find_element_by_value": { + "get_index_of_element": { "code": "array_search($element,$array)", - "name": "Find/search for an element by value" + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "min($array)", @@ -282,6 +282,10 @@ "code": "max($array)", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "in_array($element, $array)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "code": "implode($array)", "name": "Convert a list to a string" diff --git a/web/thesauruses/php/8/lists.json b/web/thesauruses/php/8/lists.json index 2f6264098..c96010622 100644 --- a/web/thesauruses/php/8/lists.json +++ b/web/thesauruses/php/8/lists.json @@ -278,9 +278,9 @@ "find_element_at_position": { "code": "$array[$n]" }, - "find_element_by_value": { + "get_index_of_element": { "code": "array_search($element,$array)", - "name": "Find/search for an element by value" + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "min($array)", @@ -290,6 +290,10 @@ "code": "max($array)", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "in_array($element, $array)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "code": "implode($array)", "name": "Convert a list to a string" diff --git a/web/thesauruses/python/3/lists.json b/web/thesauruses/python/3/lists.json index d678d0470..12263988a 100644 --- a/web/thesauruses/python/3/lists.json +++ b/web/thesauruses/python/3/lists.json @@ -256,12 +256,10 @@ "delete_immutable_set": { "not-implemented": "true" }, - "find_element_by_value": { + "get_index_of_element": { "code": [ - "value in list_name", "list_name.index(value)" - ], - "comment": "First line returns a True/False value. Second line returns an index if found or a ValueError if not found" + ] }, "find_minimum_element": { "code": [ @@ -273,6 +271,12 @@ "max(list_name)" ] }, + "contains_element": { + "code": [ + "value in list_name" + ], + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "code": [ "separator.join(list_name)" @@ -316,9 +320,22 @@ "len(list_name)" ] }, + "is_list_empty": { + "code": [ + "not list_name" + ], + "comment": "In Python, empty lists are falsy.", + "name": "Check if the list is empty" + }, "resize_list": { "not-implemented": "true" }, + "clear_list": { + "code": [ + "list_name.clear()" + ], + "name": "Remove all elements from the list" + }, "do_two_lists_match_exactly": { "code": [ "list_name1 == list_name2" @@ -369,6 +386,39 @@ }, "reduce_right": { "not-implemented": "true" + }, + "slice_list": { + "code": [ + "list_name[start:stop:step]" + ], + "comment": "Python slicing creates a shallow copy of the list.", + "name": "Get a slice/portion of a list (view or shallow copy)" + }, + "get_first_element": { + "code": [ + "list_name[0]" + ], + "name": "Get the first element" + }, + "get_last_element": { + "code": [ + "list_name[-1]" + ], + "name": "Get the last element" + }, + "remove_duplicates": { + "code": [ + "list_name = list(set(list_name))" + ], + "comment": "This method does not preserve order. For preserving order, use dict.fromkeys(list_name).", + "name": "Remove duplicate elements from the list" + }, + "flatten_list": { + "code": [ + "[item for sublist in nested_list for item in sublist]" + ], + "comment": "This is a common way to flatten a list of lists using list comprehension.", + "name": "Flatten a nested list" } } } \ No newline at end of file diff --git a/web/thesauruses/r/4/lists.json b/web/thesauruses/r/4/lists.json index cec3e393b..2c80e603e 100644 --- a/web/thesauruses/r/4/lists.json +++ b/web/thesauruses/r/4/lists.json @@ -381,11 +381,9 @@ "name": "Delete the set", "not-implemented":true }, - "find_element_by_value": { - "name": "Find/search for an element by value", - "code": [ - "" - ] + "get_index_of_element": { + "name": "Get the index of an element by value", + "code": "which(my_vector == value)" }, "find_minimum_element": { "name": "Find the minimum value in a list", @@ -399,6 +397,10 @@ "max(unlist(mylist))" ] }, + "contains_element": { + "name": "Check if the list contains a specific element", + "code": "value %in% my_vector" + }, "convert_list_to_string": { "name": "Convert a list to a string", "code": [ diff --git a/web/thesauruses/ruby/3/lists.json b/web/thesauruses/ruby/3/lists.json index b2874fc32..fc7a5a9d8 100644 --- a/web/thesauruses/ruby/3/lists.json +++ b/web/thesauruses/ruby/3/lists.json @@ -382,16 +382,13 @@ "not-implemented": true, "comment": "Immutable hashes cannot be changed." }, - "find_element_by_value": { - "name": "Find/search for an element by value", + "get_index_of_element": { + "name": "Get the index of an element by value", "code": [ - "popsicle_costs = { melon: 5, 'lemon': 3, 'orange' => 4.5, 'root beer': 4, 1 => 10 }", "fruits = ['apple', 'orange', 'tomato', 'cantaloupe']", - "fruits.index 'orange'", - "popsicle_costs.key 5", - "fruits.include? 'tomato'" + "fruits.index 'orange'" ], - "comment": "First two lines are our array and hash. Third returns the index of orange, 1 in this case. Fourth line gives the key for 5, which is melon. The last line returns true, because a tomato is a fruit." + "comment": "Returns the index of the first occurrence of the element." }, "find_minimum_element": { "name": "Find the minimum value in a list", @@ -411,6 +408,13 @@ "fruits.max" ] }, + "contains_element": { + "name": "Check if the list contains a specific element", + "code": [ + "fruits = ['apple', 'orange', 'tomato', 'cantaloupe']", + "fruits.include? 'tomato'" + ] + }, "convert_list_to_string": { "name": "Convert a list to a string", "code": [ diff --git a/web/thesauruses/swift/5/lists.json b/web/thesauruses/swift/5/lists.json index 557fa157f..fc90318e4 100644 --- a/web/thesauruses/swift/5/lists.json +++ b/web/thesauruses/swift/5/lists.json @@ -236,9 +236,9 @@ "find_element_at_position": { "code": "someArray[2]" }, - "find_element_by_value": { - "code": "someArray.firstIndex(of: \"blue\")", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "myArray.firstIndex(of: value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "someArray.min()", @@ -248,6 +248,10 @@ "code": "someArray.max()", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "myArray.contains(value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "code": "let codes = [\"abc\",\"def\",\"ghi\"] \nlet codesAsText = codes.reduce(\"\", +)", "name": "Convert a list to a string" diff --git a/web/thesauruses/typescript/4/lists.json b/web/thesauruses/typescript/4/lists.json index 564cb978e..e6532c009 100644 --- a/web/thesauruses/typescript/4/lists.json +++ b/web/thesauruses/typescript/4/lists.json @@ -227,9 +227,9 @@ "not-implemented": true, "name": "Delete the set" }, - "find_element_by_value": { - "code": "array.find((element) => element === value)", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "myArray.indexOf(value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "Math.min.apply(null, array)\nOR\nMath.min(...array)", @@ -239,6 +239,10 @@ "code": "Math.max.apply(null, array)\nOR\nMath.max(...array)", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "myArray.includes(value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "code": "array.toString()", "name": "Convert a list to a string" diff --git a/web/thesauruses/vbnet/16/lists.json b/web/thesauruses/vbnet/16/lists.json index 86a870551..1621b89fa 100644 --- a/web/thesauruses/vbnet/16/lists.json +++ b/web/thesauruses/vbnet/16/lists.json @@ -333,9 +333,9 @@ "find_element_at_position": { "code": "listName[index]" }, - "find_element_by_value": { - "code": "listName.Find(Function(x) x == value)", - "name": "Find/search for an element by value" + "get_index_of_element": { + "code": "listName.IndexOf(value)", + "name": "Get the index of an element by value" }, "find_minimum_element": { "code": "listName.Min()", @@ -345,6 +345,10 @@ "code": "listName.Max()", "name": "Find the maximum value in a list" }, + "contains_element": { + "code": "listName.Contains(value)", + "name": "Check if the list contains a specific element" + }, "convert_list_to_string": { "code": "string.Join(\", \",listName)", "name": "Convert a list to a string" From 5b3c9249f4e50cad6a1ce191128893d796c49d48 Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:28:47 -0500 Subject: [PATCH 05/10] Operators: Add null forgiving, optional chaining, spread/rest operator --- web/thesauruses/_meta/operators.json | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web/thesauruses/_meta/operators.json b/web/thesauruses/_meta/operators.json index cf826f097..a3808f486 100644 --- a/web/thesauruses/_meta/operators.json +++ b/web/thesauruses/_meta/operators.json @@ -58,7 +58,9 @@ }, "Conditional Operators": { "ternary": "Ternary operator", - "null_forgiving": "Null forgiving operator" + "null_forgiving": "Null forgiving operator", + "optional_chaining": "Optional chaining operator", + "spread_operator": "Spread/Rest operator" } } } From a31f1d3b5822f2f2d750bea8d8a800d9d8f204ba Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:34:40 -0500 Subject: [PATCH 06/10] Control Structs: Add pattern matching cases, break/continue, and with/using and defer --- web/thesauruses/_meta/control_structures.json | 7 +++++++ web/thesauruses/kotlin/1.5/control_structures.json | 7 ++++++- web/thesauruses/python/3/control_structures.json | 9 +++++++-- web/thesauruses/rust/1/control_structures.json | 8 +++++++- web/thesauruses/swift/5/control_structures.json | 8 +++++++- 5 files changed, 34 insertions(+), 5 deletions(-) diff --git a/web/thesauruses/_meta/control_structures.json b/web/thesauruses/_meta/control_structures.json index f4a24824c..001168867 100644 --- a/web/thesauruses/_meta/control_structures.json +++ b/web/thesauruses/_meta/control_structures.json @@ -10,6 +10,7 @@ "if_elseif_conditional": "If/ElseIf conditional", "if_elseif_else_conditional": "If/ElseIf/Else conditional", "switch_statement": "Switch statement", + "pattern_matching": "Pattern matching", "ternary_conditional": "Ternary conditional" }, "Loops": { @@ -19,6 +20,8 @@ "do_until_loop": "Do/Until loop", "for_loop": "For loop", "foreach_loop": "Foreach loop", + "break": "Breaking out of a loop", + "continue": "Continuing to the next iteration of a loop", "list_comprehension": "List Comprehension" }, "Iterations": { @@ -26,6 +29,10 @@ "map_iteration": "Map iteration", "filter_iteration": "Filter iteration", "fold_iteration": "Fold iteration" + }, + "Resource Management": { + "context_manager": "Context manager or with/using statement", + "defer": "Defer statement" } } } diff --git a/web/thesauruses/kotlin/1.5/control_structures.json b/web/thesauruses/kotlin/1.5/control_structures.json index 2fd4ebe0e..d735c1d02 100644 --- a/web/thesauruses/kotlin/1.5/control_structures.json +++ b/web/thesauruses/kotlin/1.5/control_structures.json @@ -28,7 +28,12 @@ }, "switch_statement": { "name": "Switch statement", - "code": "when (expression) {\n value1 -> {\n // statements\n }\n value2 -> {\n // statements\n }\n else -> {\n // statements\n }\n}" + "code": "when (x) {\n 1 -> print(\"x == 1\")\n 2 -> print(\"x == 2\")\n else -> {\n print(\"x is neither 1 nor 2\")\n }\n}" + }, + "pattern_matching": { + "name": "Pattern matching", + "comment": "Kotlin's `when` expression supports advanced pattern matching like type checks and range checks.", + "code": "when (obj) {\n 1 -> \"One\"\n \"Hello\" -> \"Greeting\"\n is Long -> \"Long\"\n !is String -> \"Not a string\"\n else -> \"Unknown\"\n}" }, "while_loop": { "name": "While loop", diff --git a/web/thesauruses/python/3/control_structures.json b/web/thesauruses/python/3/control_structures.json index c35f1d2b4..3405e87fd 100644 --- a/web/thesauruses/python/3/control_structures.json +++ b/web/thesauruses/python/3/control_structures.json @@ -23,10 +23,15 @@ "name": "If/ElseIf/Else conditional" }, "switch_statement": { - "comment": "This control structure was introduced with Python 3.10 and is more powerful than shown here.", - "code": "match condition:\n case value1:\n statements\n case value2:\n statements", + "comment": "In Python 3.10+, the `match` statement is used for both switch-like behavior and advanced pattern matching.", + "code": "match variable:\n case value1:\n # statements\n case value2:\n # statements\n case _:\n # default case", "name": "Switch statement" }, + "pattern_matching": { + "comment": "Structural Pattern Matching was introduced in Python 3.10.", + "code": "match command.split():\n case [\"quit\"]:\n quit()\n case [\"load\", filename]:\n load(filename)\n case [\"move\", x, y] if int(y) > 0:\n move(x, y)\n case _: \n print(\"Unknown command\")", + "name": "Pattern matching" + }, "ternary_conditional": { "code": "expression_if_true if condition else expression_if_false", "name": "Ternary conditional" diff --git a/web/thesauruses/rust/1/control_structures.json b/web/thesauruses/rust/1/control_structures.json index 9c922124e..61cca0e9c 100644 --- a/web/thesauruses/rust/1/control_structures.json +++ b/web/thesauruses/rust/1/control_structures.json @@ -27,9 +27,15 @@ "name": "Ternary conditional" }, "switch_statement": { - "code": "match expression {\n pattern => { statements }\n _ => { statements } // the special pattern _ matches all cases\n}", + "comment": "Rust uses the `match` keyword for switch-like behavior and exhaustive pattern matching.", + "code": "match expression {\n pattern => { statements }\n _ => { statements } // default case\n}", "name": "Switch statement" }, + "pattern_matching": { + "comment": "Rust has very powerful pattern matching capabilities with `match` and `if let`.", + "code": "match some_option {\n Some(i) if i > 5 => println!(\"Greater than five: {}\", i),\n Some(i) => println!(\"Value: {}\", i),\n None => println!(\"No value\"),\n}", + "name": "Pattern matching" + }, "while_loop": { "code": "while condition {\n statements;\n}", "name": "While loop" diff --git a/web/thesauruses/swift/5/control_structures.json b/web/thesauruses/swift/5/control_structures.json index 138ca32c6..d7ff7fd2c 100644 --- a/web/thesauruses/swift/5/control_structures.json +++ b/web/thesauruses/swift/5/control_structures.json @@ -27,9 +27,15 @@ "name": "Ternary conditional" }, "switch_statement": { - "code": "switch (expression) {\n case constant-expression:\n statements;\n break;\n default:\n statements;\n}", + "comment": "Swift switches must be exhaustive and can match many different patterns.", + "code": "switch someValue {\ncase 1:\n print(\"One\")\ncase 2...5:\n print(\"Between 2 and 5\")\ndefault:\n print(\"Something else\")\n}", "name": "Switch statement" }, + "pattern_matching": { + "comment": "Swift has powerful pattern matching in `switch`, `if case`, `guard case`, and loops.", + "code": "switch somePoint {\ncase (0, 0):\n print(\"Origin\")\ncase (_, 0):\n print(\"On the x-axis\")\ncase (0, _):\n print(\"On the y-axis\")\ncase (-2...2, -2...2):\n print(\"Near the origin\")\ndefault:\n print(\"Outside area\")\n}", + "name": "Pattern matching" + }, "while_loop": { "code": "while condition {\n statements\n}", "name": "While loop" From 3ad138f3a2e4ad786e257d797f47ede80e803cb7 Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:46:17 -0500 Subject: [PATCH 07/10] Functs: Add optional params, async, named arguments, extension function, multiple return types --- web/thesauruses/_meta/functions.json | 10 +++++++ .../javascript/ECMAScript 2023/functions.json | 22 +++++++++++++++ web/thesauruses/python/3/functions.json | 28 +++++++++++++++++++ web/thesauruses/swift/5/functions.json | 5 ++++ 4 files changed, 65 insertions(+) diff --git a/web/thesauruses/_meta/functions.json b/web/thesauruses/_meta/functions.json index 8d4ea82f7..bbd5b87f9 100644 --- a/web/thesauruses/_meta/functions.json +++ b/web/thesauruses/_meta/functions.json @@ -8,29 +8,39 @@ "void_function_no_parameters": "Function that does not return a value and takes no parameters", "void_function_with_parameters": "Function that does not return a value and that takes 1 or more defined parameters", "void_function_with_keyword_parameters": "Function that does not return a value and that takes 0 or more defined keyword parameters", + "void_function_with_optional_parameters": "Function that does not return a value and that takes 1 or more optional parameters (with default values)", "void_function_variable_parameters": "Function that does not return a value and function that takes an unknown number of parameters" }, "Return Value Functions": { "return_value_function_no_parameters": "Function that returns a value and takes no parameters", "return_value_function_with_parameters": "Function that returns a value and takes 1 or more defined parameters", "return_value_function_with_keyword_parameters": "Function that returns a value and takes 0 or more defined keyword parameters", + "return_value_function_with_optional_parameters": "Function that returns a value and takes 1 or more optional parameters (with default values)", "return_value_function_variable_parameters": "Function that returns a value and takes an unknown number of parameters" }, "Lambda/Anonymous Functions": { "anonymous_function_no_parameters": "Anonymous function that takes no parameters", "anonymous_function_with_parameters": "Anonymous function that takes 1 or more defined parameters", "anonymous_function_with_keyword_parameters": "Anonymous function that takes 0 or more defined keyword parameters", + "anonymous_function_with_optional_parameters": "Anonymous function that takes 1 or more optional parameters (with default values)", "anonymous_function_variable_parameters": "Anonymous function that takes an unknown number of parameters" }, "Lambda/Anonymous Functions with Return Value": { "anonymous_function_no_parameters_with_return": "Anonymous function that takes no parameters and returns a value", "anonymous_function_with_parameters_with_return": "Anonymous function that takes 1 or more defined parameters and returns a value", "anonymous_function_with_keyword_parameters_with_return": "Anonymous function that takes 0 or more defined keyword parameters and returns a value", + "anonymous_function_with_optional_parameters_with_return": "Anonymous function that takes 1 or more optional parameters (with default values) and returns a value", "anonymous_function_variable_parameters_with_return": "Anonymous function that takes an unknown number of parameters and returns a value" }, "Subroutines": { "call_subroutine": "Call subroutine", "return_from_subroutine": "Return from subroutine" + }, + "Modern Function Features": { + "async_function": "Asynchronous function (async/await)", + "named_arguments": "Named arguments in function calls", + "extension_function": "Extension functions", + "multiple_return_values": "Multiple return values" } } } diff --git a/web/thesauruses/javascript/ECMAScript 2023/functions.json b/web/thesauruses/javascript/ECMAScript 2023/functions.json index 6e5994629..ca2086098 100644 --- a/web/thesauruses/javascript/ECMAScript 2023/functions.json +++ b/web/thesauruses/javascript/ECMAScript 2023/functions.json @@ -18,6 +18,10 @@ "name": "Function that does not return a value and that takes 0 or more defined keyword parameters", "code": "function method({param1, param2}) {\n}" }, + "void_function_with_optional_parameters": { + "name": "Function that does not return a value and that takes 1 or more optional parameters (with default values)", + "code": "function method(param1, param2 = 'default') {\n}" + }, "void_function_variable_parameters": { "name": "Function that does not return a value and function that takes an unknown number of parameters", "code": "function method(...params) {\n}" @@ -34,6 +38,10 @@ "name": "Function that returns a value and takes 0 or more defined keyword parameters", "code": "function method({param1, param2}) {\n return true;\n}" }, + "return_value_function_with_optional_parameters": { + "name": "Function that returns a value and takes 1 or more optional parameters (with default values)", + "code": "function method(param1, param2 = 'default') {\n return true;\n}" + }, "return_value_function_variable_parameters": { "name": "Function that returns a value and takes an unknown number of parameters", "code": "function method(...params) {\n return true;\n}" @@ -59,6 +67,13 @@ "const method = ({param1, param2}) => {\n}" ] }, + "anonymous_function_with_optional_parameters": { + "name": "Anonymous function that takes 1 or more optional parameters (with default values)", + "code": [ + "const method = function(param1, param2 = 'default') {\n}", + "const method = (param1, param2 = 'default') => {\n}" + ] + }, "anonymous_function_variable_parameters": { "name": "Anonymous function that takes an unknown number of parameters", "code": [ @@ -87,6 +102,13 @@ "const method = ({param1, param2}) => true" ] }, + "anonymous_function_with_optional_parameters_with_return": { + "name": "Anonymous function that takes 1 or more optional parameters (with default values) and returns a value", + "code": [ + "const method = function(param1, param2 = 'default') {\n return true;\n}", + "const method = (param1, param2 = 'default') => true" + ] + }, "anonymous_function_variable_parameters_with_return": { "name": "Anonymous function that takes an unknown number of parameters and returns a value", "code": [ diff --git a/web/thesauruses/python/3/functions.json b/web/thesauruses/python/3/functions.json index 068cc1f60..62ecd2711 100644 --- a/web/thesauruses/python/3/functions.json +++ b/web/thesauruses/python/3/functions.json @@ -14,6 +14,10 @@ "code": "def function_name(parameter, parameter_1):\n statements", "name": "Function that does not return a value and that takes 1 or more defined parameters" }, + "void_function_with_optional_parameters": { + "code": "def function_name(param1, param2=default_value):\n statements", + "name": "Function that does not return a value and that takes 1 or more optional parameters (with default values)" + }, "void_function_variable_parameters": { "code": "def function_name(*parameter_name):\n statements", "name": "Function that does not return a value and function that takes an unknown number of parameters" @@ -26,6 +30,10 @@ "code": "def function_name(parameter, parameter_1):\n statements\n return expression", "name": "Function that returns a value and takes 1 or more defined parameters" }, + "return_value_function_with_optional_parameters": { + "code": "def function_name(param1, param2=default_value):\n statements\n return expression", + "name": "Function that returns a value and takes 1 or more optional parameters (with default values)" + }, "return_value_function_variable_parameters": { "code": "def function_name(*parameter_name):\n statements\n return expression", "name": "Function that returns a value and takes an unknown number of parameters" @@ -38,9 +46,29 @@ "name": "Anonymous function that takes 1 or more defined parameters", "code": "lambda parameter,parameter_1 : expression" }, + "anonymous_function_with_optional_parameters": { + "name": "Anonymous function that takes 1 or more optional parameters (with default values)", + "code": "lambda param1, param2=default_value: expression" + }, "anonymous_function_variable_parameters": { "name": "Anonymous function that takes an unknown number of parameters", "code": "lambda *parameter : expression" + }, + "anonymous_function_no_parameters_with_return": { + "name": "Anonymous function that takes no parameters and returns a value", + "code": "lambda: expression" + }, + "anonymous_function_with_parameters_with_return": { + "name": "Anonymous function that takes 1 or more defined parameters and returns a value", + "code": "lambda parameter,parameter_1 : expression" + }, + "anonymous_function_with_optional_parameters_with_return": { + "name": "Anonymous function that takes 1 or more optional parameters (with default values) and returns a value", + "code": "lambda param1, param2=default_value: expression" + }, + "anonymous_function_variable_parameters_with_return": { + "name": "Anonymous function that takes an unknown number of parameters and returns a value", + "code": "lambda *parameter : expression" } } } diff --git a/web/thesauruses/swift/5/functions.json b/web/thesauruses/swift/5/functions.json index b82e600f6..415b1b7e8 100644 --- a/web/thesauruses/swift/5/functions.json +++ b/web/thesauruses/swift/5/functions.json @@ -55,6 +55,11 @@ "code": "return", "comment": "If entire function body is a single expression, no return keyword needed to return expression.", "name": "Return from subroutine" + }, + "extension_function": { + "code": "extension SomeType {\n func newFunction() {\n // statements\n }\n}", + "comment": "Extensions add new functionality to an existing class, structure, enumeration, or protocol type.", + "name": "Extension functions" } } } From 056d652004f51543161d61aa26fb08bafdcfb238 Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:50:45 -0500 Subject: [PATCH 08/10] Language basics: Add syntax/style, naming, scoping, package management, error handling, and variable declarations --- web/thesauruses/_meta/language_basics.json | 33 +++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/web/thesauruses/_meta/language_basics.json b/web/thesauruses/_meta/language_basics.json index 0de09acf0..687b631d1 100644 --- a/web/thesauruses/_meta/language_basics.json +++ b/web/thesauruses/_meta/language_basics.json @@ -19,12 +19,19 @@ }, "Execution Method": { "compiled_language": "Language is translated into machine code or an intermediate form by a compiler before execution", - "interpreted_language": "Language is executed line by line by an interpreter at runtime withot a separate compilation step" + "interpreted_language": "Language is executed line by line by an interpreter at runtime without a separate compilation step" }, "Application Domain": { "general_purpose_language": "Language is designed to be versatile and applicable to a wide range of tasks and applications", "domain_specific_language": "Language is designed to address specific application domains or industries" }, + "Syntax and Style": { + "case_sensitive": "Language distinguishes between uppercase and lowercase characters in identifiers", + "case_insensitive": "Language does not distinguish between uppercase and lowercase characters in identifiers", + "significant_whitespace": "Indentation or whitespace has semantic meaning in the language", + "insignificant_whitespace": "Indentation or whitespace does not have semantic meaning, often using braces or other delimiters", + "statement_terminators": "The characters or methods used to signal the end of a statement (e.g., semicolons, newlines)" + }, "Memory Management": { "manual_management": "Languages where memory has to be managed by the programmer manually", "automatic_management": "Languages with an extensive support of automatic memory management" @@ -35,6 +42,26 @@ "third_generation": "High-level programming languages designed for general-purpose software development, offering a higher level of abstraction and greater ease of use compared to low-level languages like assembly.", "fourth_generation": "High-level programming languages designed for specific applications or domains, often using natural language-like syntax and focusing on rapid application development." }, + "Naming Conventions": { + "variable_naming": "The standard convention for naming variables (e.g., snake_case, camelCase)", + "function_naming": "The standard convention for naming functions or methods", + "class_naming": "The standard convention for naming classes or types (e.g., PascalCase)" + }, + "Scoping": { + "lexical_scoping": "Variable scope is determined by its position in the source code", + "dynamic_scoping": "Variable scope is determined by the program's runtime call stack", + "block_scoping": "Variables are scoped to the nearest enclosing block (usually marked by braces or indentation)", + "function_scoping": "Variables are scoped to the nearest enclosing function" + }, + "Package Management": { + "primary_package_manager": "The primary tool used for managing dependencies and libraries", + "central_repository": "The main public repository for sharing and downloading packages" + }, + "Error Handling": { + "exception_based": "Errors are handled using an exception-throwing mechanism (try/catch/finally)", + "return_code_based": "Errors are handled by checking return values or status codes", + "type_based": "Errors are handled using functional types like Result, Option, or Either" + }, "Entry Point": { "main_function": "Entry point of the program is the main function of the file", "custom_function": "In some programming languages, custom functions can be made to be the entry point of a program", @@ -50,6 +77,10 @@ "standard_libraries": "Programming Language is supported by an extensive network of standard libraries which are not required to be imported externally", "extensive_frameworks": "Language has a strong network of external frameworks for supporting additional functionalities. Usually the external libraries are installed into the project using a package manager, and imported into the required file using the `import` keyword" }, + "Variable Declaration": { + "mutable_variable": "Declaring a mutable variable", + "immutable_variable": "Declaring an immutable variable/constant" + }, "Minimal Program": { "hello_world": "The most minimal program to understand all the basics is the Hello World program. Here you only need to print \"Hello World\" to the console/output of the programming language of your choice." } From 2a240d030ea28f3561f937ea86651bd56e21cd2a Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 16:51:25 -0500 Subject: [PATCH 09/10] Kotlin functions, Python 3 IO (as remnants of other tasks) --- web/thesauruses/kotlin/1.5/functions.json | 75 +++++++++++++++++++++++ web/thesauruses/python/3/io.json | 72 ++++++++++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 web/thesauruses/kotlin/1.5/functions.json create mode 100644 web/thesauruses/python/3/io.json diff --git a/web/thesauruses/kotlin/1.5/functions.json b/web/thesauruses/kotlin/1.5/functions.json new file mode 100644 index 000000000..cf9e70ebc --- /dev/null +++ b/web/thesauruses/kotlin/1.5/functions.json @@ -0,0 +1,75 @@ +{ + "meta": { + "language": "kotlin", + "language_name": "Kotlin", + "structure": "functions", + "language_version": "1.5" + }, + "concepts": { + "void_function_no_parameters": { + "code": "fun functionName() {\n // statements\n}", + "name": "Function that does not return a value and takes no parameters" + }, + "void_function_with_parameters": { + "code": "fun functionName(param1: Type, param2: Type) {\n // statements\n}", + "name": "Function that does not return a value and that takes 1 or more defined parameters" + }, + "void_function_with_optional_parameters": { + "code": "fun functionName(param1: Type, param2: Type = defaultValue) {\n // statements\n}", + "name": "Function that does not return a value and that takes 1 or more optional parameters (with default values)" + }, + "void_function_variable_parameters": { + "code": "fun functionName(vararg params: Type) {\n // statements\n}", + "name": "Function that does not return a value and function that takes an unknown number of parameters" + }, + "return_value_function_no_parameters": { + "code": "fun functionName(): ReturnType {\n // statements\n return expression\n}", + "name": "Function that returns a value and takes no parameters" + }, + "return_value_function_with_parameters": { + "code": "fun functionName(param1: Type, param2: Type): ReturnType {\n // statements\n return expression\n}", + "name": "Function that returns a value and takes 1 or more defined parameters" + }, + "return_value_function_with_optional_parameters": { + "code": "fun functionName(param1: Type, param2: Type = defaultValue): ReturnType {\n // statements\n return expression\n}", + "name": "Function that returns a value and takes 1 or more optional parameters (with default values)" + }, + "return_value_function_variable_parameters": { + "code": "fun functionName(vararg params: Type): ReturnType {\n // statements\n return expression\n}", + "name": "Function that returns a value and takes an unknown number of parameters" + }, + "anonymous_function_no_parameters": { + "code": "{ -> // statements }", + "name": "Anonymous function that takes no parameters" + }, + "anonymous_function_with_parameters": { + "code": "{ param1: Type, param2: Type -> // statements }", + "name": "Anonymous function that takes 1 or more defined parameters" + }, + "anonymous_function_variable_parameters": { + "not-implemented": true, + "name": "Anonymous function that takes an unknown number of parameters" + }, + "anonymous_function_no_parameters_with_return": { + "code": "{ -> expression }", + "name": "Anonymous function that takes no parameters and returns a value" + }, + "anonymous_function_with_parameters_with_return": { + "code": "{ param1: Type, param2: Type -> expression }", + "name": "Anonymous function that takes 1 or more defined parameters and returns a value" + }, + "extension_function": { + "code": "fun ReceiverType.functionName() {\n // statements\n}", + "comment": "Extension functions allow you to add new functions to existing classes without inheriting from them.", + "name": "Extension functions" + }, + "named_arguments": { + "code": "functionName(param2 = value2, param1 = value1)", + "name": "Named arguments in function calls" + }, + "async_function": { + "code": "suspend fun functionName() {\n // statements\n}", + "name": "Asynchronous function (async/await)" + } + } +} diff --git a/web/thesauruses/python/3/io.json b/web/thesauruses/python/3/io.json new file mode 100644 index 000000000..8064d5312 --- /dev/null +++ b/web/thesauruses/python/3/io.json @@ -0,0 +1,72 @@ +{ + "meta": { + "language": "python", + "language_version": "3", + "language_name": "Python", + "structure": "io" + }, + "concepts": { + "write_line": { + "code": "print(content, end='')" + }, + "write_line_with_new_line": { + "code": "print(content)" + }, + "read_line": { + "code": "variable = input(prompt)" + }, + "clear_console_output": { + "code": [ + "import os", + "os.system('cls' if os.name == 'nt' else 'clear')" + ] + }, + "file_functions_lib": { + "code": "import os" + }, + "list_directory": { + "code": "os.listdir(path)" + }, + "create_directory": { + "code": "os.mkdir(path)" + }, + "delete_directory": { + "code": "os.rmdir(path)" + }, + "check_file_exists": { + "code": "os.path.isfile(path)" + }, + "check_directory_exists": { + "code": "os.path.isdir(path)" + }, + "get_file_size": { + "code": "os.path.getsize(path)" + }, + "get_file_last_modified": { + "code": "os.path.getmtime(path)" + }, + "get_environment_variable": { + "code": "os.environ.get('VARIABLE_NAME')" + }, + "set_environment_variable": { + "code": "os.environ['VARIABLE_NAME'] = 'value'" + }, + "list_all_environment_variables": { + "code": "os.environ" + }, + "create_temporary_file": { + "code": [ + "import tempfile", + "with tempfile.NamedTemporaryFile(delete=False) as fp:", + " fp.write(content)" + ] + }, + "create_temporary_directory": { + "code": [ + "import tempfile", + "with tempfile.TemporaryDirectory() as tmpdirname:", + " print('created temporary directory', tmpdirname)" + ] + } + } +} From 25639b2112147c207a2555f09c52e6e1505b0b1f Mon Sep 17 00:00:00 2001 From: Sarah Withee <2601974+geekygirlsarah@users.noreply.github.com> Date: Sat, 27 Dec 2025 17:05:36 -0500 Subject: [PATCH 10/10] Optimize and modernize/make more robust the validate lang/meta info files commands --- .../commands/validatelanginfofiles.py | 275 ++++++++---------- .../commands/validatemetainfofile.py | 129 ++++---- 2 files changed, 185 insertions(+), 219 deletions(-) diff --git a/web/management/commands/validatelanginfofiles.py b/web/management/commands/validatelanginfofiles.py index 5a0a8dd49..e6c35e38f 100644 --- a/web/management/commands/validatelanginfofiles.py +++ b/web/management/commands/validatelanginfofiles.py @@ -1,165 +1,132 @@ -import os import json +from pathlib import Path from django.core.management.base import BaseCommand, CommandError -from web.models import MetaInfo - class Command(BaseCommand): help = "Reads all language JSON files to ensure they're constructed correctly" - def handle(self, *args, **options): - error_count = 0 - warning_count = 0 + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.error_count = 0 + self.warning_count = 0 + self.thesauruses_path = Path("web/thesauruses") - # Open up thesaurus directory - language_dirs = os.listdir("web/thesauruses/") - for lang_dir in language_dirs: - if lang_dir == "_meta": - continue - if os.path.isfile("web/thesauruses/" + lang_dir): + def handle(self, *args, **options): + for lang_dir in self.thesauruses_path.iterdir(): + if not lang_dir.is_dir() or lang_dir.name == "_meta": continue - # Open up each version directory - versions = os.listdir("web/thesauruses/" + lang_dir) - for version in versions: - # Open up each structures file - structure_files = os.listdir("web/thesauruses/" + lang_dir + "/" + version) - for structure_file in structure_files: - structure = structure_file[:-5] - - # Ensure valid lang/version/name - meta_structure_file_path = os.path.join( - "web", "thesauruses", lang_dir, version, structure) + ".json" - - # parse file - with open(meta_structure_file_path, 'r') as meta_structure_file: - raw_file_data = meta_structure_file.read() - - meta_structure_file_json = json.loads(raw_file_data) - - language = meta_structure_file_json["meta"]["language"] - language_version = meta_structure_file_json["meta"]["language_version"] - language_name = meta_structure_file_json["meta"]["language_name"] - relative_path_name = lang_dir + "/" + version + "/" + structure + ".json" - - if not language: - print( - f"[Error] `{relative_path_name}` has an empty `language` attribute and needs to be updated") - error_count += 1 - elif language == "language_id": - print( - f"[Error] `{relative_path_name}` has the default `language` attribute and needs to be updated") - error_count += 1 - elif not language == lang_dir: - print( - f"[Error] `{relative_path_name}` has a `language` attribute that should be `{lang_dir}` and needs to be updated") - error_count += 1 - - if not language_version: - print( - f"[Error] `{relative_path_name}` has an empty `language_version` attribute and needs to be updated") - error_count += 1 - elif language_version == "version.number": - print( - f"[Error] `{relative_path_name}` has the default `language_version` attribute and needs to be updated") - error_count += 1 - - if not language_name: - print( - f"[Error] `{relative_path_name}` has an empty `language_name` attribute and needs to be updated") - error_count += 1 - elif language_name == "Human-Friendly Language Name" or language_name == "Human-Readable Language Name": - print( - f"[Error] `{relative_path_name}` has the default `language_name` attribute and needs to be updated") - error_count += 1 - - # Ensure categories aren't in file - if "categories" in meta_structure_file_json: - print( - f"[Error] `{relative_path_name}` has a `categories` section in it, which is now deprecated") - error_count += 1 - - # Ensure name lines are removed - for item in meta_structure_file_json["concepts"]: - structure_item_data = meta_structure_file_json["concepts"][item] - - # This generates SO many warnings that I'm commenting it out for now. Consider uncommenting - # when more errors and such have been resolved - # if "name" in structure_item_data: - # print(f"[Warn] `{relative_path_name}`, ID: `{item}` has a `name` line that can be " - # f"removed") - # warning_count += 1 - - # Ensure there's either code or not-implemented - has_code = "code" in structure_item_data - has_not_implemented = "not-implemented" in structure_item_data - has_not_underscore_implemented = "not_implemented" in structure_item_data - has_comments_plural = "comments" in structure_item_data - - # Ensure they use not-implemented (hyphen) not not_implemented (underscore) - if has_not_underscore_implemented: - print(f"[Error] `{relative_path_name}`, ID: `{item}` has not_implemented (underscore) " - f"when it should use not-implemented (hyphen)") - error_count += 1 - - if has_code and (has_not_implemented or has_not_underscore_implemented): - print( - f"[Error] `{relative_path_name}`, ID: `{item}` should have `code` or " - f"`not-implemented`, not both") - error_count += 1 - - if not has_code and not has_not_implemented and not has_not_underscore_implemented: - print( - f"[Error] `{relative_path_name}`, ID: `{item}` is missing a needed `code` or " - f"`not-implemented` line") - error_count += 1 - - # Ensure if not-implemented, there's no code line - if has_not_implemented and structure_item_data["not-implemented"] is True and has_code: - print(f"[Error] `{relative_path_name}`, ID: `{item}` is not implemented, but has a " - f"`code` line that should be removed") - error_count += 1 - - # Ensure if code, it's not empty and there's no not-implemented - if has_code and not structure_item_data["code"] and not has_not_implemented: - print(f"[Error] `{relative_path_name}`, ID: `{item}` is confusing: `code` is empty " - f"but there's no `not-implemented` either") - error_count += 1 - - # Ensure it's comment, not comments - if has_comments_plural: - print(f"[Error] `{relative_path_name}`, ID: `{item}` has `comments` (plural) that " - f"should be `comment` (singular) instead") - error_count += 1 - - # Code can be string or array (maybe warn if string) - # if has_code and isinstance(structure_item_data["code"], str): - # print(f"[Warning] `{relative_path_name}`, ID: `{item}` has a `code` line that's a " - # f"string and could optionally be an array") - # warning_count += 1 - - # There shouldn't be any other fields - for key in structure_item_data: - if not (key == "code" - or key == "comment" - or key == "comments" - or key == "not-implemented" - or key == "not_implemented" - or key == "name"): - # Why "not_implemented"/"name"/"comments"? Because we check for them above, - # this checks for other exceptions - print(f"[Warning] `{relative_path_name}`, ID: `{item}` has a line `{key}` that's " - f"unknown") - warning_count += 1 - - if warning_count + error_count > 0: - # if error_count > 0: - if warning_count: - print(str(warning_count) + " warnings found.") - if error_count: - print(str(error_count) + " errors found.") - raise CommandError(str(error_count) + " errors found.") - else: - print("No issues found.") + for version_dir in lang_dir.iterdir(): + if not version_dir.is_dir(): + continue + + for structure_file in version_dir.glob("*.json"): + self.validate_language_file(structure_file) + + if self.warning_count > 0: + self.stdout.write(self.style.WARNING(f"{self.warning_count} warnings found.")) + + if self.error_count > 0: + self.stdout.write(self.style.ERROR(f"{self.error_count} errors found.")) + raise CommandError(f"{self.error_count} errors found.") + + if self.error_count == 0 and self.warning_count == 0: + self.stdout.write(self.style.SUCCESS("No issues found.")) + + def report_error(self, message): + self.stderr.write(self.style.ERROR(f"[Error] {message}")) + self.error_count += 1 + + def report_warning(self, message): + self.stdout.write(self.style.WARNING(f"[Warning] {message}")) + self.warning_count += 1 + + def validate_language_file(self, file_path): + relative_path = file_path.relative_to(self.thesauruses_path) + + try: + with open(file_path, 'r', encoding='utf-8') as f: + data = json.load(f) + except (json.JSONDecodeError, UnicodeDecodeError) as e: + self.report_error(f"Failed to parse `{relative_path}`: {e}") + return + + self.check_meta_section(data, relative_path) + self.check_concepts(data, relative_path) + + def check_meta_section(self, data, relative_path): + meta = data.get("meta", {}) + # relative_path is something like "python/3/data_types.json" + # parts[0] is the language directory name + lang_dir = relative_path.parts[0] + + language = meta.get("language") + language_version = meta.get("language_version") + language_name = meta.get("language_name") + + if not language: + self.report_error(f"`{relative_path}` has an empty `language` attribute and needs to be updated") + elif language == "language_id": + self.report_error(f"`{relative_path}` has the default `language` attribute and needs to be updated") + elif language != lang_dir: + self.report_error(f"`{relative_path}` has a `language` attribute that should be `{lang_dir}` and needs to be updated") + + if not language_version: + self.report_error(f"`{relative_path}` has an empty `language_version` attribute and needs to be updated") + elif language_version == "version.number": + self.report_error(f"`{relative_path}` has the default `language_version` attribute and needs to be updated") + + if not language_name: + self.report_error(f"`{relative_path}` has an empty `language_name` attribute and needs to be updated") + elif language_name in ["Human-Friendly Language Name", "Human-Readable Language Name"]: + self.report_error(f"`{relative_path}` has the default `language_name` attribute and needs to be updated") + + if "categories" in data: + self.report_error(f"`{relative_path}` has a `categories` section in it, which is now deprecated") + + def check_concepts(self, data, relative_path): + concepts = data.get("concepts", {}) + for concept_id, item_data in concepts.items(): + has_code = "code" in item_data + has_not_implemented = "not-implemented" in item_data + has_not_underscore_implemented = "not_implemented" in item_data + has_comments_plural = "comments" in item_data + + if has_not_underscore_implemented: + self.report_error( + f"`{relative_path}`, ID: `{concept_id}` has not_implemented (underscore) " + "when it should use not-implemented (hyphen)" + ) + + if has_code and (has_not_implemented or has_not_underscore_implemented): + self.report_error( + f"`{relative_path}`, ID: `{concept_id}` should have `code` or `not-implemented`, not both" + ) + + if not has_code and not has_not_implemented and not has_not_underscore_implemented: + self.report_error( + f"`{relative_path}`, ID: `{concept_id}` is missing a needed `code` or `not-implemented` line" + ) + + if has_not_implemented and item_data.get("not-implemented") is True and has_code: + self.report_error( + f"`{relative_path}`, ID: `{concept_id}` is not implemented, but has a `code` line that should be removed" + ) + + if has_code and not item_data.get("code") and not has_not_implemented: + self.report_error( + f"`{relative_path}`, ID: `{concept_id}` is confusing: `code` is empty but there's no `not-implemented` either" + ) + + if has_comments_plural: + self.report_error( + f"`{relative_path}`, ID: `{concept_id}` has `comments` (plural) that should be `comment` (singular) instead" + ) + + # Check for unknown keys + allowed_keys = {"code", "comment", "not-implemented", "not_implemented", "name", "comments"} + for key in item_data: + if key not in allowed_keys: + self.report_warning(f"`{relative_path}`, ID: `{concept_id}` has a line `{key}` that's unknown") diff --git a/web/management/commands/validatemetainfofile.py b/web/management/commands/validatemetainfofile.py index e0a8011ba..1fe975b41 100644 --- a/web/management/commands/validatemetainfofile.py +++ b/web/management/commands/validatemetainfofile.py @@ -1,6 +1,4 @@ -import os -import json -# import sys +from pathlib import Path from django.core.management.base import BaseCommand, CommandError @@ -10,71 +8,72 @@ class Command(BaseCommand): help = "Validate the structure of the meta info file" + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.error_count = 0 + self.metainfo = None + self.thesauruses_path = Path("web/thesauruses") + self.meta_path = self.thesauruses_path / "_meta" + def handle(self, *args, **options): - error_count = 0 - warning_count = 0 - metainfo = MetaInfo() + self.metainfo = MetaInfo() + + self.check_thesaurus_directories() + self.check_meta_info_consistency() + self.check_meta_files_consistency() + + if self.error_count > 0: + raise CommandError(f"{self.error_count} errors found.") + + self.stdout.write(self.style.SUCCESS("No errors found in meta_info.json.")) + + def report_error(self, message): + self.stderr.write(self.style.ERROR(f"[Error] {message}")) + self.error_count += 1 - # Look through thesaurus directories, see if any files don't match - # Load MetaInfo, check directories are in MetaInfo - meta_files = os.listdir("web/thesauruses/_meta") + def check_thesaurus_directories(self): + """Look through thesaurus directories, see if any files don't match""" + meta_files = {f.name for f in self.meta_path.iterdir() if f.is_file()} - for lang in os.listdir("web/thesauruses"): - if lang == "_meta": + for lang_dir in self.thesauruses_path.iterdir(): + if not lang_dir.is_dir() or lang_dir.name == "_meta": continue - path = "web/thesauruses/" + lang - if os.path.isdir(path): - - if not lang in list(metainfo.languages): - print(f"[Error] `{path}` exists but {lang} is not listed as a language in `meta_info.json`") - error_count += 1 - - versions = os.listdir(path) - for version in versions: - if os.path.isfile(path + "/" + version): - print(f"[Error] `{path}/{version}` is a file but a directory for a version was expected") - error_count += 1 - continue - - structures = os.listdir(path + "/" + version) - for structure in structures: - # concept_path = "web/thesauruses/" + lang + "/" + version + concept - if structure not in meta_files: - print(f"[Error] `{path}/{version}/{structure}` is not a valid concept filename") - error_count += 1 - - # Check all language directories exist - for meta_lang in metainfo.languages: - path = "web/thesauruses/" + meta_lang - if not os.path.isdir(path): - print( - f"[Error] {metainfo.languages[meta_lang]} is listed as a language in `meta_info.json` but the " - f"directory doesn't exist") - error_count += 1 - - # Check structures are in MetaInfo + + lang = lang_dir.name + if lang not in self.metainfo.languages: + self.report_error(f"`{lang_dir}` exists but {lang} is not listed as a language in `meta_info.json`") + + for version_dir in lang_dir.iterdir(): + if version_dir.is_file(): + self.report_error(f"`{version_dir}` is a file but a directory for a version was expected") + continue + + for structure_file in version_dir.iterdir(): + if structure_file.name not in meta_files: + self.report_error(f"`{structure_file}` is not a valid concept filename") + + def check_meta_info_consistency(self): + """Check all language directories exist for languages listed in meta_info.json""" + for meta_lang in self.metainfo.languages: + path = self.thesauruses_path / meta_lang + if not path.is_dir(): + lang_name = self.metainfo.languages[meta_lang] + self.report_error(f"{lang_name} is listed as a language in `meta_info.json` but the directory `{path}` doesn't exist") + + def check_meta_files_consistency(self): + """Check structures in _meta match those in MetaInfo""" + meta_files = {f.name for f in self.meta_path.iterdir() if f.is_file()} + + # Check files in _meta are listed in MetaInfo for meta_file in meta_files: + if not meta_file.endswith(".json"): + continue structure_name = meta_file[:-5] - if structure_name not in list(metainfo.structures): # .data_structures.values()): - print( - f"[Error] `web/thesauruses/_meta/{meta_file}` is not listed as a structure in `meta_info.json`") - error_count += 1 - - # Check all concept files exist in _meta - for structure in metainfo.structures: - path = "web/thesauruses/_meta/" + structure + ".json" - if not os.path.isfile(path): - print( - f"[Error] {structure} is listed as a structure in `meta_info.json` but the `web/thesauruses/_meta/{structure}.json` file doesn't exist") - error_count += 1 - - - # if warning_count + error_count > 0: - if error_count > 0: - # if warning_count: - # print(str(warning_count) + " warnings found.") - if error_count: - # print(str(error_count) + " errors found.") - raise CommandError(str(error_count) + " errors found.") - else: - print("No errors found in meta_info.json.") + if structure_name not in self.metainfo.structures: + self.report_error(f"`{self.meta_path / meta_file}` is not listed as a structure in `meta_info.json`") + + # Check structures listed in MetaInfo have corresponding files in _meta + for structure in self.metainfo.structures: + path = self.meta_path / f"{structure}.json" + if not path.is_file(): + self.report_error(f"{structure} is listed as a structure in `meta_info.json` but the `{path}` file doesn't exist")