Goto

Collaborating Authors

 plumber


Mario's super-sized mushroom exists in real life

Popular Science

Mario's super-sized mushroom exists in real life While they actually power-up trees and not plumbers, the 40 year-old video game helped make toadstools mainstream. Mario's expansive world is modeled after the real-life mushroom'Amanita muscaria.' We may earn revenue from the products available on this page and participate in affiliate programs. Nintendo's is undisputedly one the most iconic and successful video games ever made, with more than 58 million copies sold worldwide. Even if you've never played the original game or any of the hundreds of titles that span the expansive Mario Universe, you've undoubtedly seen Mario or his brother Luigi with their matching hats, dungarees, and mustaches, jumping up and breaking bricks to uncover fire flower or super mushroom power-ups along the way.


AI Is Coming for Amateur Novelists. That's Fine.

The Atlantic - Technology

With a name that sounds like something a parent would slowly mouth to their infant, NaNoWriMo is an annual "challenge" in which many thousands of seemingly well-adjusted people decide to write a novel in a month. "Do I need something special to write a novel?" the nonprofit that puts on this exquisite torture reasonably asks on its website. National Novel Writing Month began in 1999 with 21 participants, and now nearly half a million take part every November. The event is also the name of the organization that gamifies the exercise, hosting participants on its online platform. To "win" NaNoWriMo, you need to produce a minimum of 50,000 words in a month (about the length of The Great Gatsby)--or 1,667 words a day, a number, NaNoWriMo tells us, that "scientists have determined to be the perfect amount to boost your creativity."


Assessing the influence of attractor-verb distance on grammatical agreement in humans and language models

arXiv.org Artificial Intelligence

Subject-verb agreement in the presence of an attractor noun located between the main noun and the verb elicits complex behavior: judgments of grammaticality are modulated by the grammatical features of the attractor. For example, in the sentence "The girl near the boys likes climbing", the attractor (boys) disagrees in grammatical number with the verb (likes), creating a locally implausible transition probability. Here, we parametrically modulate the distance between the attractor and the verb while keeping the length of the sentence equal. We evaluate the performance of both humans and two artificial neural network models: both make more mistakes when the attractor is closer to the verb, but neural networks get close to the chance level while humans are mostly able to overcome the attractor interference. Additionally, we report a linear effect of attractor distance on reaction times. We hypothesize that a possible reason for the proximity effect is the calculation of transition probabilities between adjacent words. Nevertheless, classical models of attraction such as the cue-based model might suffice to explain this phenomenon, thus paving the way for new research. Data and analyses available at https://osf.io/d4g6k


'Super Mario Bros. Wonder' Is the Face of Nintendo's Transformation

WIRED

Nintendo is having a very good year. The Legend of Zelda: Tears of the Kingdom was a record-breaking success; Switch sales continue to climb even in the console's sixth year. In February, the company opened Super Nintendo World at Universal Studios in California. All of this, though, looks small compared to the hype around the company's ubiquitous moustachioed plumber. This summer, The Super Mario Bros. Movie brought in nearly $1.4 billion globally at the box office, making it the second highest grossing animated film of all time.


Silicon Valley's Oracles Are Reviving a False Prophecy

Slate

This article was co-published with Understanding AI, a newsletter that explores how A.I. works and how it's changing our world. In 2011, venture capitalist Marc Andreessen published an essay that became a kind of manifesto for Silicon Valley during the 2010s. "Software is eating the world," Andreessen declared. Computers and the internet had already revolutionized a bunch of information-oriented businesses: books, movies, music, photography, telecommunications, and so forth. Software also played a major supporting role in more tangible industries. New cars had dozens of computer chips in them, for example, and the oil and gas industry made heavy use of software to discover new drilling sites. But Andreessen, co-founder of the venture capital firm Andreessen Horowitz, argued that the software revolution was only getting started.


API as a package: Structure

#artificialintelligence

This is part one of our three part series Part 1: API as a package: Structure (this post) Part 2: API as a package: Logging (to be published) Part 3: API as a package: Testing (to be published) Introduction At Jumping Rivers we were recently tasked with taking a prototype application built in {shiny} to a public facing production environment for a public sector organisation. During the scoping exercise it was determined that a more appropriate solution to fit the requirements was to build the application with a {plumber} API providing the interface to the Bayesian network model and other application tools written in R. When building applications in {shiny} we have for some time been using the โ€œapp as a packageโ€ approach which has been popularised by tools like {golem} and {leprechaun}, in large part due to the convenience that comes with leveraging the testing and dependency structure that our R developers are comfortable with in authoring packages, and the ease with which one can install and run an application in a new environment as a result. For this project we looked to take some of these ideas to a {plumber} application. This blog post discusses some of the thoughts and resultant structure that came as a result of that process. As I began to flesh out this blog post I realised that it was becoming very long, and there were a number of different aspects that I wanted to discuss: structure, logging and testing to name a few. To try to keep this a bit more palatable I will instead do a mini-series of blog posts around the API as a package idea and focus predominantly on the structure elements here. Do you use RStudio Pro? If so, checkout out our managed RStudio services API as a package There are a few things I really like about the {shiny} app as a package approach that I wanted to reflect in the design and build of a {plumber} application as package. It encourages a regular structure and organisation for an application. All modules have a consistent naming pattern and structure. It encourages leveraging the {testthat} package and including some common tests across a series of applications, see golem::use_reccommended_tests() for example. An instance of the app can be created via a single function call which does all the necessary set up, say my_package::run_app() Primarily I wanted these features, which could be reused across {plumber} applications that we create both internally and for our clients. As far as I know there isnโ€™t a similar package that provides an opinionated way of laying out a {plumber} application as a package, and it is my intention to create one as a follow up to this work. Regular structure When developing the solution for this particular project I did have in the back of my mind that I wanted to create as much reusable structure for any future projects of this sort as possible. I really wanted to have an easy way to, from a package structure, be able to build out an API with nested routes, using code that could easily transfer to another package. I opted for a structure that utilised the inst/extdata/api/routes directory of a package as a basis with the idea that the following file structure | inst/extdata/api/routes/ | | - model.R | - reports/ - | | - pdf.R with example route definitions inside # model.R #* @post /prediction exported_function_from_my_package # pdf.R #* @post /weekly exported_function_from_my_package would translate to an API with the following endpoints /model/prediction /reports/pdf/weekly A few simple function definitions would allow us to do this for any given package that uses this file structure. The first function here just grabs the directory from the current package where I will define the endpoints that make up my API. get_internal_routes = function(path = ".") { system.file("extdata", "api", "routes", path, package = utils::packageName(), mustWork = TRUE) } create_routes will recursively list out all of the .R files within the chosen directory and name them according to the name of the file, this will make it easy to build out a a number of โ€œnestedโ€ routers that will all be mounted into the same API, achieving the compartmentalisation that we desire. For example the two files at /inst/extdata/api/routes/model.R and /inst/extdata/api/routes/reports/pdf.R will take on the names "model" and "reports/pdf" respectively. add_default_route_names = function(routes, dir) { names = stringr::str_remove(routes, pattern = dir) names = stringr::str_remove(names, pattern = "\.R$") names(routes) = names routes } create_routes = function(dir) { routes = list.files( dir, recursive = TRUE, full.names = TRUE, pattern = "*\.R$" ) add_default_route_names(routes, dir) } The final few pieces to the puzzle ensure that we have / at the beginning of a string (ensure_slash()), for the purpose of mounting components to my router. add_plumber_definition() just calls the necessary functions from {plumber} to process a new route file, i.e from the decorated functions in the file create the routes, and then mount them at a given path to an existing router object. For example given a file โ€œtest.Rโ€ that has a #* @get /identity decorator against a function definition and endpoint = "test" we would add /test/identity to the existing router. generate_api() takes a full named vector/list of file paths, ensures they all have an appropriate name and mounts them all to a new Plumber router object. ensure_slash = function(string) { has_slash = grepl("^/", string) if (has_slash) string else paste0("/", string) } add_plumber_definition = function(pr, endpoint, file, ...) { router = plumber::pr(file = file, ...) plumber::pr_mount(pr = pr, path = endpoint, router = router ) } generate_api = function(routes, ...) { endpoints = purrr::map_chr(names(routes), ensure_slash) purrr::reduce2( .x = endpoints, .y = routes, .f = add_plumber_definition, ..., .init = plumber::pr(NULL) ) } With these defined I can then, as I develop my package, add new routes by defining functions and adding {plumber} tag annotations to files in /inst/ and rebuild the new API with get_internal_routes() %>% create_routes() %>% generate_api() and nothing about this code is specific to my current package so is transferable. As a concrete, but very much simplified example, I might have the following collection of files/annotations under /inst/extdata/api/routes ## File: /example.R # Taken from plumber quickstart documentation # https://www.rplumber.io/articles/quickstart.html #* @get /echo function(msg="") { list(msg = paste0("The message is: '", msg, "'")) } ## File: /test.R #* @get /is_alive function() { list(alive = TRUE) } ## File: /nested/example.R # Taken from plumber quickstart documentation # https://www.rplumber.io/articles/quickstart.html #* @get /echo function(msg="") { list(msg = paste0("The message is: '", msg, "'")) } which would give me get_internal_routes() %>% create_routes() %>% generate_api() # # Plumber router with 0 endpoints, 4 filters, and 3 sub-routers. # # Use `pr_run()` on this object to start the API. # โ”œโ”€โ”€[queryString] # โ”œโ”€โ”€[body] # โ”œโ”€โ”€[cookieParser] # โ”œโ”€โ”€[sharedSecret] # โ”œโ”€โ”€/example # โ”‚ โ”‚ # Plumber router with 1 endpoint, 4 filters, and 0 sub-routers. # โ”‚ โ”œโ”€โ”€[queryString] # โ”‚ โ”œโ”€โ”€[body] # โ”‚ โ”œโ”€โ”€[cookieParser] # โ”‚ โ”œโ”€โ”€[sharedSecret] # โ”‚ โ””โ”€โ”€/echo (GET) # โ”œโ”€โ”€/nested # โ”‚ โ”œโ”€โ”€/example # โ”‚ โ”‚ โ”‚ # Plumber router with 1 endpoint, 4 filters, and 0 sub-routers. # โ”‚ โ”‚ โ”œโ”€โ”€[queryString] # โ”‚ โ”‚ โ”œโ”€โ”€[body] # โ”‚ โ”‚ โ”œโ”€โ”€[cookieParser] # โ”‚ โ”‚ โ”œโ”€โ”€[sharedSecret] # โ”‚ โ”‚ โ””โ”€โ”€/echo (GET) # โ”œโ”€โ”€/test # โ”‚ โ”‚ # Plumber router with 1 endpoint, 4 filters, and 0 sub-routers. # โ”‚ โ”œโ”€โ”€[queryString] # โ”‚ โ”œโ”€โ”€[body] # โ”‚ โ”œโ”€โ”€[cookieParser] # โ”‚ โ”œโ”€โ”€[sharedSecret] # โ”‚ โ””โ”€โ”€/is_alive (GET) This {cookieCutter} example is available to view at our Github blog repo. Basic testing In my real project I refrained from having any actual function definitions being made in inst/. Instead each function that was part of the exposed API was a proper exported function from my package (additionally filenames for said functions followed a regular structure too of api_.R). This allows for leveraging {testthat} against the logic of each of the functions as well as using other tools like {lintr} and ensuring that dependencies, documentation etc are all dealt with appropriately. Testing individual functions that will be exposed as routes can be a little different to other R functions in that the objects passed as arguments come from a request. As alluded to in the introduction I will prepare another blog post detailing some elements of testing for API as a package but a short snippet that I found particularly helpful for testing that a running API is functioning as I expect is included here. The following code could be used to set up (and subsequently tear down) a running API that is expecting requests for a package cookieCutter # tests/testthat/setup.R ## run before any tests # pick a random available port to serve your app locally port = httpuv::randomPort() # start a background R process that launches an instance of the API # serving on that random port running_api = callr::r_bg( function(port) { dir = cookieCutter::get_internal_routes() routes = cookieCutter::create_routes(dir) api = cookieCutter::generate_api(routes) api$run(port = port, host = "0.0.0.0") }, list(port = port) ) # Small wait for the background process to ensure it # starts properly Sys.sleep(1) ## run after all tests withr::defer(running_api$kill(), testthat::teardown_env()) A simple test to ensure that our is_alive endpoint works then might look like test_that("is alive", { res = httr::GET(glue::glue("http://0.0.0.0:{port}/test/is_alive")) expect_equal(res$status_code, 200) }) Logging {shiny} has some useful packages for adding logging, in particular {shinylogger} is very helpful at giving you plenty of logging for little effort on my part as the user. As far as I could find nothing similar exists for {plumber} so I set up a bunch of hooks, using the {logger} package to write information to both file and terminal. Since that could form itโ€™s own blogpost I will save that discussion for the future. For updates and revisions to this article, see the original post


Train and deploy ML models with R and plumber on Vertex AI

#artificialintelligence

R is one of the most widely used programming languages for statistical computing and machine learning. Many data scientists love it, especially for the rich world of packages from tidyverse, an opinionated collection of R packages for data science. Besides the tidyverse, there are over 18,000 open-source packages on CRAN, the package repository for R. RStudio, available as desktop version or on the Google Cloud Marketplace, is a popular Integrated Development Environment (IDE) used by data professionals for visualization and machine learning model development. Once a model has been built successfully, a recurring question among data scientists is: "How do I deploy models written in the R language to production in a scalable, reliable and low-maintenance way?" In this blog post, you will walk through how to use Google Vertex AI to train and deploy enterprise-grade machine learning models built with R. Managing machine learning models on Vertex AI can be done in a variety of ways, including using the User Interface of the Google Cloud Console, API calls, or the Vertex AI SDK for Python.


The Golden Rule as a Heuristic to Measure the Fairness of Texts Using Machine Learning

arXiv.org Artificial Intelligence

To treat others as one would wish to be treated is a common formulation of the golden rule (GR). Yet, despite its prevalence as an axiom throughout history, no transfer of this moral philosophy into computational systems exists. In this paper we consider how to algorithmically operationalise this rule so that it may be used to measure sentences such as the boy harmed the girl, and categorise them as fair or unfair. For the purposes of the paper, we define a fair act as one that one would be accepting of if it were done to oneself. A review and reply to criticisms of the GR is made. We share the code for the digitisation of the GR, and test it with a list of sentences. Implementing it within two language models, the USE, and ALBERT, we find F1 scores of 78.0, 85.0, respectively. A suggestion of how the technology may be implemented to avoid unfair biases in word embeddings is made - given that individuals would typically not wish to be on the receiving end of an unfair act, such as racism, irrespective of whether the corpus being used deems such discrimination as praiseworthy.


AI Needs To Learn Multi-Intent For Computers To Show Empathy

#artificialintelligence

Artificial Intelligence (AI) is smart, but it could do better. The software development industry is constantly working to push algorithmic logic beyond the scope of the current computer processing envelope and create new ways for computers to'think' and emulate human beings. We have of course progressed significantly onward from the fanciful notions of AI that were characterized in the Sci-Fi movies of the 1980s. Largely as result of access to massively more powerful processors and massively larger (and eminently accessible) datasets -- and as a result of cloud computing and modern approaches to database management, we can now create an impressive amount of smartness in the AI that we now develop. But AI needs to get smarter.


Why We Love How-to Videos - Issue 79: Catalysts

Nautilus

An insistent pattern has quietly taken hold in my household. I will order some consumer product online. I will open the package, extract the thing from its protective wrappings, and retrieve the instruction manual. I will examine the product briefly, then begin to read the instruction manual. And then I will go to YouTube.