Giter Club home page Giter Club logo

ensurer's People

Contributors

ironholds avatar kbroman avatar rgknight avatar smbache avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ensurer's Issues

Adding common checks

Is this planned? E.g. ensure_string_scalar, ensure_file_exists, ensure_dir_exists, etc? Or the idea is that I can just add to my package whatever I need?

Try-error forwarding by ensure()

Hello,

I wonder if try-errors could be forwarded in the same desirable way as normal errors are handled by the ensure() function:

require(ensurer)
require(magrittr)
stop("I want to see this error.") %>%
ensure(is.character, fail_with = stop("I don't want to see this error")
try({stop("I want to see this error.")}) %>%
ensure(is.character, fail_with = stop("I don't want to see this error"))

Include the name of the object in the error message

I promise that this is the last one for today. :)

As much as I like the dot notation, I think it would be good to see that name of the object that breached the contract (if it has a name at all). Often the name is informative. I would not replace the dot itself, but I think something like this looks good and is more informative:

ensure_small_even <- ensures_that( . < 50, . %% 2 == 0)
f <- function() {
   value <- 101
   ensure_small_even(value)
}
f()
Error:  assertions failed for 'value' in 'f':
     ✖ all(. < 50)
     ✖ all(. %% 2 == 0)

It might be challenging to implement this, though. In the ensurer function, deparse(sys.call(-1)[[1]]) gives the function name, and deparse(sys.call()[[2]]) gives the argument name, this is easy.

But of course you can have anonymous functions, and you can also wrap ensurer functions, in which cases this is more difficult. You would probably need API to wrap an ensurer function. E.g. I am doing this now:

ensure_character_scalar <- function(x) {
  x %>%
    ensure_that(is.character(.)) %>%
    ensure_that(length(.) == 1)
}

Which is not bad, but ensure_character_scalar is not an ensurer function, just a plain one.

And other strange cases might exist, that I am unaware of.

Custom error message

I guess this is possible with fail_with, but it seems rather cumbersome. When I do something like

ensure_that(x, attr %in% names(attributes(.)))

the error message looks as

Error:  The following condition failed:
     * attr %in% names(attributes(.))

and I would rather like something like

Error:  The following condition failed:
     * has no attribute 'name'

Post to cran?

Thanks for your work on this.

I quite like this package and considering using it as a dependency in a data cleaning package.

What are the chances that this package will make its way to a release version on CRAN?

I'm less interested in the type stability stuff than I am in having a lightweight way to create runtime contracts with custom error messages for use in production processes.

(Note that I have the same question about loggr -- love that package as well).

Wish: Define global fail_with function

Dear @smbache,
Thanks a lot for this great package. I am frequently using it to ensure that data I read in from CSVs/data bases does not change unnoticed as well as that all my calculation stay in certain borders and no NAs suddenly occur after changes. As my alert system I use a fail_with function that forwards the error respective message to Slack (an instant messenger), which works great.

In practice every data source I read into R has its own functions (like get_customer_data(), get_sales_data(), ...). Each of these functions contains chained ensure_that statements that check for various cases. Following data operations are packed with ensurer checks as well.

Example:

# Error detection
  dim_country %>%
    ensurer::ensure_that(is.data.frame(.), fail_with = ensurer_fail_function) %>%
    ensurer::ensure_that(ncol(.) == 2, fail_with = ensurer_fail_function) %>%
    ensurer::ensure_that(nrow(.) > 1, fail_with = ensurer_fail_function) %>%
    # Prevent duplicates
    ensurer::ensure_that(length(.$country_code) == length(unique(.$country_code)), fail_with = ensurer_fail_function) %>%
    ensurer::ensure_that(length(.$country) == length(unique(.$country)), fail_with = ensurer_fail_function) %>%
    # No NAs in relevant columns
    ensurer::ensure_that(any(is.na(.$country_code)) == FALSE, fail_with = ensurer_fail_function) %>%
    ensurer::ensure_that(any(is.na(.$country)) == FALSE, fail_with = ensurer_fail_function) %>% 
    invisible(.)

As you can see, I have multiple cases I want to check. However, I have to provide each time that I want to call my individual fail_with function. This is tedious to code and one easily misses to enter an indivual fail_with function.

Wish/idea

  • Allow to set the fail_with option globally (which would be the default if a global value is set).

I see the possibility to use ensures_that here, which in the example above would reduce the time I type in fail_with = ensurer_fail_function to one for that example. However, in my case, I have around 20 different places with ensurer checks in one single complex script. That means even with ensures_that, I would still end up with having to define this 20 times with the same fail_with option for the whole script. Thus, my wish for a global option to define a fail_with function.

I am perfectly fine, if you disagree with me on this and say that you deem ensures_that as the solution to my wish. ;-) Again, thanks a lot for providing this useful package!

More succinct errors:

EDIT sorry, pressed enter by mistake.

I think being brief and succinct is a virtue. So how about

Errors: * all(. < 50)
        * all(.%%2 == 0)

instead of

Error:  The following condition(s) failed:
     * all(. < 50)
     * all(.%%2 == 0)

Extend a contract

I have an ensurer function that I want to extend, ideally without writing out the full original contract again. I think currently the best I can do is putting the original and the new contracts together with a pipe (%,% or %>%). This is not bad, but unfortunately behaves slightly differently, as it does not list all errors, if there are some both in the original contract and in the additional one.

Would you consider some API to extend a contract?

Checks without error

Just an idea that came up as I was writing checks. It would be often useful to run the checks and get a TRUE/FALSE result instead of an error, similarly to see_if in assertthat.

Right now I need to duplicate the code for this, or use a single expression in ensure_that:

is_adjmatrix <- function(x) (is.matrix(x) || is(x, "Matrix")) && nrow(x) == ncol(x)
ensure_adjmatrix <- ensures_that(is_adjmatrix(.))

But then of course individual failed conditions are not reported.

Just an idea to think about.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.