datacamp / testwhat

Write Submission Correctness Tests for R exercises
https://datacamp.github.io/testwhat
GNU Affero General Public License v3.0
33 stars 24 forks source link

Positional matching of arguments #208

Closed richierocks closed 5 years ago

richierocks commented 5 years ago

For cases where we pass unnamed arguments to functions , particularly those that have a ... signature, it would be great to be able to match the argument by position rather than name.

For example, you want the studetns to use dplyr to filter a data frame.

cars %>% 
   filter(speed > 20, dist < 100)

Currently, the SCTs look like

ex() %>% check_correct(
  check_output_expr(., "cars %>% filter(speed > 20)"),
  check_function(., filter") %>% {
    check_code(., "speed > 20")  
    check_code(., "dist < 100")  
  }
)

I'd prefer to be able to check the arguments

ex() %>% check_correct(
  check_output_expr(., "cars %>% filter(speed > 20)"),
  check_function(., filter") %>% {
    check_arg(., 1) %>% check_equal()
    check_arg(., 2) %>% check_equal() 
  }
)
richierocks commented 5 years ago

Related: the arguments inside ... can be accessed using ..1, ..2, etc., or via ...elt(n). So being able to specify

ex() %>% check_correct(
  check_output_expr(., "cars %>% filter(speed > 20)"),
  check_function(., filter") %>% {
    check_arg(., "..1") %>% check_equal()
    check_arg(., "..2") %>% check_equal() 
  }
)

is another possibility.

machow commented 5 years ago

@richierocks just passing through, but out of curiosity--when you say match by position, which of these has correctly ordered argument positions when the function is called? (by use of ... guessing the second?)

Call expression: always ordered in position specified in code

f <- function(a, ..., b) 1

call <- as.call(quote(f(b = 1,2,3, a = 4)))
print(call)
# > f(b = 1, 2, 3, a = 4)

or

Call evaluation: ordered by matching with function signature

f <- function(a, ..., b) print(match.call())

f(b = 4, 2, 3, a = 1)
# > f(a = 1, 2, 3, b = 4)
richierocks commented 5 years ago

This has sort of shipped. There's still an open issue here https://datacamp.atlassian.net/servicedesk/customer/portal/1/DESK-860, but I think we can close this.

richierocks commented 5 years ago

@machow I think that it should be the first one: whatever the student types.

Though we should only ever need this for functions where there are unnamed args in ... (we can and should match by name otherwise), so it shouldn't matter either way.