Skip to content

Commit 94c0095

Browse files
committed
add snakecase helper and human_name default
1 parent f49af3f commit 94c0095

File tree

2 files changed

+65
-13
lines changed

2 files changed

+65
-13
lines changed

src/StatisticalTraits.jl

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const TRAITS = [
2121
:supports_online,
2222
:docstring,
2323
:name,
24+
:human_name,
2425
:is_supervised,
2526
:prediction_type,
2627
:hyperparameters,
@@ -60,6 +61,40 @@ function typename(M)
6061
end
6162
end
6263

64+
function is_uppercase(char::Char)
65+
i = Int(char)
66+
i > 64 && i < 91
67+
end
68+
69+
"""
70+
snakecase(str, del='_')
71+
72+
Return the snake case version of the abstract string or symbol, `str`, as in
73+
74+
snakecase("TheLASERBeam") == "the_laser_beam"
75+
76+
"""
77+
function snakecase(str::AbstractString; delim='_')
78+
snake = Char[]
79+
n = length(str)
80+
for i in eachindex(str)
81+
char = str[i]
82+
if is_uppercase(char)
83+
if i != 1 && i < n &&
84+
!(is_uppercase(str[i + 1]) && is_uppercase(str[i - 1]))
85+
push!(snake, delim)
86+
end
87+
push!(snake, lowercase(char))
88+
else
89+
push!(snake, char)
90+
end
91+
end
92+
return join(snake)
93+
end
94+
95+
snakecase(s::Symbol) = Symbol(snakecase(string(s)))
96+
97+
6398

6499
## TRAITS
65100

@@ -96,10 +131,12 @@ prediction_type(::Type) = :unknown # used for measures too
96131

97132
# Miscellaneous:
98133

99-
is_wrapper(::Type) = false # or `true`
100-
supports_online(::Type) = false # or `true`
101-
docstring(M::Type) = string(M) # some `String`
102-
is_supervised(::Type) = false # or `true`
134+
is_wrapper(::Type) = false # or `true`
135+
supports_online(::Type) = false # or `true`
136+
docstring(M::Type) = string(M) # some `String`
137+
is_supervised(::Type) = false # or `true`
138+
human_name(M::Type) = snakecase(name(M), delim=' ') # `name` defined below
139+
103140

104141
# Returns a tuple, with one entry per field of `T` (the type of some
105142
# statistical model, for example). Each entry is `nothing` or defines

test/runtests.jl

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import SparseArrays
55

66
module Fruit
77

8-
struct Apple end
8+
struct RedApple end
99

1010
end
1111

@@ -17,11 +17,19 @@ import .Fruit
1717
@testset "typename" begin
1818
@test StatisticalTraits.typename(Nothing) == :Nothing
1919
@test StatisticalTraits.typename(UnionAll) == :UnionAll
20-
@test StatisticalTraits.typename(Union{Char,Int}) == Symbol("Union{Char, Int64}")
20+
@test StatisticalTraits.typename(Union{Char,Int}) ==
21+
Symbol("Union{Char, Int64}")
2122
T = SparseArrays.sparse([1,2], [1,3], [0.5, 0.6]) |> typeof
2223
@test StatisticalTraits.typename(T) == :SparseMatrixCSC
2324
end
2425

26+
@testset "snakecase" begin
27+
@test StatisticalTraits.snakecase("AnthonyBlaomsPetElk") ==
28+
"anthony_blaoms_pet_elk"
29+
@test StatisticalTraits.snakecase("TheLASERBeam", delim=' ') ==
30+
"the laser beam"
31+
end
32+
2533

2634
## TRAITS WITH NON-CONSTANT FALL-BACK
2735

@@ -32,28 +40,34 @@ end
3240

3341
@testset "docstring" begin
3442
@test docstring(Foo(1,'x')) == "Foo"
35-
@test docstring(Fruit.Apple()) == "Main.Fruit.Apple"
43+
@test docstring(Fruit.RedApple()) == "Main.Fruit.RedApple"
3644
end
3745

3846
@testset "hyperparameter_ranges" begin
3947
@test hyperparameter_ranges(Foo(1, 'x')) == (nothing, nothing)
40-
@test hyperparameter_ranges(Fruit.Apple()) == ()
48+
@test hyperparameter_ranges(Fruit.RedApple()) == ()
4149
end
4250

4351
@testset "name" begin
4452
@test name(Float64) == "Float64"
45-
@test name(Fruit.Apple) == "Apple"
46-
@test name(Fruit.Apple()) == "Apple"
53+
@test name(Fruit.RedApple) == "RedApple"
54+
@test name(Fruit.RedApple()) == "RedApple"
55+
end
56+
57+
@testset "human_name" begin
58+
@test human_name(AbstractString) == "abstract string"
59+
@test human_name(Fruit.RedApple) == "red apple"
60+
@test human_name(Fruit.RedApple()) == "red apple"
4761
end
4862

4963
@testset "hyperparameters" begin
5064
@test hyperparameters(Foo(1, 'x')) == (:x, :y)
51-
@test hyperparameters(Fruit.Apple()) == ()
65+
@test hyperparameters(Fruit.RedApple()) == ()
5266
end
5367

5468
@testset "hyperparameter_types" begin
5569
@test hyperparameter_types(Foo(1, 'x')) == ("Int64", "Char")
56-
@test hyperparameter_types(Fruit.Apple()) == ()
70+
@test hyperparameter_types(Fruit.RedApple()) == ()
5771
end
5872

5973

@@ -62,13 +76,14 @@ end
6276
const NONCONSTANT = [:docstring,
6377
:hyperparameter_ranges,
6478
:name,
79+
:human_name,
6580
:hyperparameters,
6681
:hyperparameter_types]
6782

6883
@testset "traits with constant fall-back" begin
6984
for trait in setdiff(StatisticalTraits.TRAITS, NONCONSTANT)
7085
ex = quote
71-
@test $trait(Fruit.Apple()) == $trait(Foo(1, 'x'))
86+
@test $trait(Fruit.RedApple()) == $trait(Foo(1, 'x'))
7287
end
7388
Main.eval(ex)
7489
end

0 commit comments

Comments
 (0)