Skip to content

Commit

Permalink
Recommend mean((x, y)) rather than middle((x, y)) (#147)
Browse files Browse the repository at this point in the history
It seems more logical and simpler for users to recommend using the
same function.

Also fix checking exception.
  • Loading branch information
nalimilan authored Aug 28, 2023
1 parent f54010d commit 04e5d89
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 6 deletions.
10 changes: 7 additions & 3 deletions src/Statistics.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,13 @@ if !isdefined(Base, :mean)
function mean(f::Number, itr::Number)
f_value = try
f(itr)
catch MethodError
rethrow(ArgumentError("""mean(f, itr) requires a function and an iterable.
Perhaps you meant middle(x, y)?""",))
catch err
if err isa MethodError && err.f === f && err.args == (itr,)
rethrow(ArgumentError("""mean(f, itr) requires a function and an iterable.
Perhaps you meant mean((x, y))?"""))
else
rethrow(err)
end
end
Base.reduce_first(+, f_value)/1
end
Expand Down
12 changes: 9 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,18 @@ end
@test isnan(@inferred mean(Iterators.filter(x -> true, Float64[])))

# using a number as a "function"
@test_throws "ArgumentError: mean(f, itr) requires a function and an iterable.\nPerhaps you meant middle(x, y)" mean(1, 2)
@test_throws "ArgumentError: mean(f, itr) requires a function and an iterable.\nPerhaps you meant mean((x, y))" mean(1, 2)
struct T <: Number
x::Int
end
(t::T)(y) = t.x * y
@test @inferred mean(T(2), 3) === 6.0
(t::T)(y) = t.x == 0 ? t(y, y + 1, y + 2) : t.x * y
@test mean(T(2), 3) === 6.0
@test_throws MethodError mean(T(0), 3)
struct U <: Number
x::Int
end
(t::U)(y) = t.x == 0 ? throw(MethodError(T)) : t.x * y
@test @inferred mean(U(2), 3) === 6.0
end

@testset "mean/median for ranges" begin
Expand Down

0 comments on commit 04e5d89

Please sign in to comment.