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

timearray: Revoke deprecation of == and redefine its meaning #357

Merged
merged 9 commits into from
Dec 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
### 0.12.0

* Revoking deprecation warning of `==` and redefining its meaning as
'comparing all fields of two `TimeArray`s'.
Note that if two `TimeArray`s have different dimension, we consider that is
unequal.
(#356, #357)

```julia
julia> cl == copy(cl)
true
```

* Also, `isequal` and `hash` is supported now.

```julia
julia> d = Dict(cl => 42);

julia> d[cl]
42

julia> d[copy(cl)]
42
```

### 0.11.0

* Dropping 0.5 support. (issue [#327])
Expand Down
2 changes: 1 addition & 1 deletion src/deprecated.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ for f ∈ (:^, :/)
end

for f ∈ (:+, :-, :*, :%,
:|, :&, :<, :>, :(==), :(!=), :>=, :<=)
:|, :&, :<, :>, :>=, :<=)
g = Symbol(".", string(f))
@eval import Base: $f
@eval @deprecate $f(ta::TimeArray, args...) $g(ta, args...)
Expand Down
38 changes: 36 additions & 2 deletions src/timearray.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
###### type definition ##########

import Base: convert, copy, length, show, getindex, start, next, done, isempty,
endof, size, eachindex
endof, size, eachindex, ==, isequal, hash

abstract type AbstractTimeSeries end

Expand Down Expand Up @@ -69,13 +69,47 @@ length(ata::AbstractTimeSeries) = length(ata.timestamp)

size(ta::TimeArray, dim...) = size(ta.values, dim...)

###### iterator protocol #########
###### iterator protocol ########

start(ta::TimeArray) = 1
next(ta::TimeArray, i) = ((ta.timestamp[i], ta.values[i, :]), i + 1)
done(ta::TimeArray, i) = (i > length(ta))
isempty(ta::TimeArray) = (length(ta) == 0)

###### equal ####################

"""
==(x::TimeArray, y::TimeArray)

If `true`, all fields of `x` and `y` should be equal,
meaning that the two `TimeArray`s have the same values at the same points in time,
the same colnames and the same metadata.

Implies

```julia
x.timestamp == y.timestamp &&
x.values == y.values &&
x.colnames == y.colnames &&
x.meta == y.meta
```
"""
# Other type info is not helpful for assertion.
# e.g.
# 1.0 == 1
# Date(2111, 1, 1) == DateTime(2111, 1, 1)
==(x::TimeArray{T,N}, y::TimeArray{S,M}) where {T,S,N,M} = false
==(x::TimeArray{T,N}, y::TimeArray{S,N}) where {T,S,N} =
all(f -> getfield(x, f) == getfield(y, f), fieldnames(TimeArray))

isequal(x::TimeArray{T,N}, y::TimeArray{S,M}) where {T,S,N,M} = false
isequal(x::TimeArray{T,N}, y::TimeArray{S,N}) where {T,S,N} =
all(f -> isequal(getfield(x, f), getfield(y, f)), fieldnames(TimeArray))

# support for Dict
hash(x::TimeArray, h::UInt) =
sum(f -> hash(getfield(x, f), h), fieldnames(TimeArray))

###### show #####################

@inline _showval(v::Any) = repr(v)
Expand Down
51 changes: 51 additions & 0 deletions test/timearray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,57 @@ end
end


@testset "equal" begin
@test cl == copy(cl)
@test cl ≠ ohlc # rely on fallback definition
@test cl ≠ lag(cl)

@test isequal(cl, copy(cl))
@test !isequal(cl, ohlc)
@test !isequal(cl, lag(cl))

ds = DateTime(2017, 12, 25):DateTime(2017, 12, 31) |> collect

let # diff colnames
x = TimeArray(ds, 1:7, ["foo"])
y = TimeArray(ds, 1:7, ["bar"])
@test x != y
end

let # Float vs Int
x = TimeArray(ds, 1:7)
y = TimeArray(ds, 1.0:7)
@test x == y
end

let # Date vs DateTime
ds2 = Date(2017, 12, 25):Date(2017, 12, 31) |> collect
x = TimeArray(ds, 1:7, ["foo"], "bar")
y = TimeArray(ds2, 1:7, ["foo"], "bar")
@test x == y
end

let # diff meta
x = TimeArray(ds, 1:7, ["foo"], "bar")
y = TimeArray(ds, 1:7, ["foo"], "baz")
@test x != y
end

@testset "hash" begin
@test hash(cl) == hash(copy(cl))
@test hash(ohlc) == hash(copy(ohlc))

d = Dict(cl => 42)
@test d[cl] == 42
@test d[copy(cl)] == 42

d = Dict(ohlc => 24)
@test d[ohlc] == 24
@test d[copy(ohlc)] == 24
end
end


@testset "show methods don't throw errors" begin
let str = sprint(show, cl)
out = """500x1 TimeSeries.TimeArray{Float64,1,Date,Array{Float64,1}} 2000-01-03 to 2001-12-31
Expand Down