Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export problem() and problem_message() #124

Merged
merged 26 commits into from
Aug 29, 2022
Merged

Conversation

gadenbuie
Copy link
Member

@gadenbuie gadenbuie commented Aug 19, 2022

This PR exposes some of the problem-related infrastructure of tblcheck, in particular making it easier for other packages to construct problem objects with problem() and to extend the problem_message generic.

  1. We now export problem()
  2. I renamed tblcheck_message() to problem_message() and moved it next to the other code related to the problem class.
  3. We now export problem_message() too
  4. I renamed tblcheck_grade() to problem_grade() since this also better describes the generic.

Now that everything is together I think there's a strong case for the generics to live in gradethis — we even called the problem a gradethis_problem. I also think this is the perfect use-case for R7, so I think we should wait until that's available on CRAN and then move the problem generics into gradethis and migrate to R7 at the same time.

@gadenbuie gadenbuie self-assigned this Aug 19, 2022
Copy link
Contributor

@rossellhayes rossellhayes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think exporting the generic and eventually moving it to gradethis sounds great to me! My one question is whether we should give these functions a prefixed name, like gradethis_problem_*(). Is problem() too generic of a name for an exported function, or is that not an issue?

@nischalshrestha
Copy link
Contributor

I think exporting the generic and eventually moving it to gradethis sounds great to me! My one question is whether we should give these functions a prefixed name, like gradethis_problem_*(). Is problem() too generic of a name for an exported function, or is that not an issue?

Yeah grade_this_problem() could maybe be like the root of all grading problems, and it gets more specific after that when other packages have their own problems.

@gadenbuie
Copy link
Member Author

Is problem() too generic of a name for an exported function, or is that not an issue?

I think it's okay and it fits right in with fail(), pass() etc... Do you know of any packages providing a problem generic? Also I wonder if/how R7 might help with package conflicts like this, I bet they've thought of something.

Update with added .class argument

problem() works in basically the same way that it used to…

problem <- problem(
  type = "foo",
  expected = 1,
  actual = 2,
  correct = FALSE
)
str(problem)
#> List of 4
#>  $ type    : chr "foo"
#>  $ expected: num 1
#>  $ actual  : num 2
#>  $ correct : logi FALSE
#>  - attr(*, "class")= chr [1:3] "foo_problem" "tblcheck_problem" "gradethis_problem"

But you can now provide custom classes via .class that replace the <type>_problem and tblcheck_problem classes.

problem <- problem(
  type = "foo",
  expected = 1,
  actual = 2,
  correct = FALSE,
  .class = c("foo_problem", "other_pkg_problem")
)
str(problem)
#> List of 4
#>  $ type    : chr "foo"
#>  $ expected: num 1
#>  $ actual  : num 2
#>  $ correct : logi FALSE
#>  - attr(*, "class")= chr [1:3] "foo_problem" "other_pkg_problem" "gradethis_problem"

This lets type become a human-readable problem type message (it still needs to be a scalar), but if you use a type that doesn’t form a valid class, you’ll get an error.

problem(
  type = "foo isn't right",
  expected = 1,
  actual = 2,
  correct = FALSE
)
#> Error in `problem()`:
#> ! `.class` must be a character vector of valid R class names

Which can be avoided by providing .class.

problem <- problem(
  type = "foo isn't right",
  expected = 1,
  actual = 2,
  correct = FALSE,
  .class = "foo_problem"
)
str(problem)
#> List of 4
#>  $ type    : chr "foo isn't right"
#>  $ expected: num 1
#>  $ actual  : num 2
#>  $ correct : logi FALSE
#>  - attr(*, "class")= chr [1:2] "foo_problem" "gradethis_problem"

From there, you can use problem_type() to access the type, but if you want to check the type of the problem in the sense of it’s class, you can use is_problem().

problem_type(problem)
#> [1] "foo isn't right"
# Checks for both class 'foo' or 'foo_problem'
is_problem(problem, "foo")
#> [1] TRUE
is_problem(problem, "foo_problem")
#> [1] TRUE

Note that while is_problem() will try to help you out, is_tblcheck_problem() is more strict.

class(problem) <- c("foo", "tblcheck_problem", "gradethis_problem")
is_tblcheck_problem(problem, "foo")
#> [1] FALSE

class(problem) <- c("foo_problem", "tblcheck_problem", "gradethis_problem")
is_tblcheck_problem(problem, "foo")
#> [1] TRUE

Copy link
Contributor

@nischalshrestha nischalshrestha left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I like how things are slowly getting more generalizable/extendible, and it'll be even better once generics move to gradethis.

@gadenbuie gadenbuie merged commit fe26b70 into main Aug 29, 2022
@gadenbuie gadenbuie deleted the feat/export-tblcheck-message branch August 29, 2022 16:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants