Skip to content

Commit 4812a10

Browse files
committed
Better error handling
1 parent 159581a commit 4812a10

File tree

1 file changed

+37
-17
lines changed

1 file changed

+37
-17
lines changed

src/Bijections.jl

+37-17
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,12 @@ struct Bijection{S,T} <: AbstractDict{S,T}
2121
R = Set{T}()
2222
F = Dict{S,T}()
2323
G = Dict{T,S}()
24-
new(D,R,F,G)
24+
new(D, R, F, G)
2525
end
2626

2727
# private, unsafe constructor
28-
function Bijection{S,T}(D::Set{S},R::Set{T},F::Dict{S,T},G::Dict{T,S}) where {S,T}
29-
new(D,R,F,G)
28+
function Bijection{S,T}(D::Set{S}, R::Set{T}, F::Dict{S,T}, G::Dict{T,S}) where {S,T}
29+
new(D, R, F, G)
3030
end
3131
end
3232

@@ -53,24 +53,44 @@ function Bijection(x::S, y::T) where {S,T}
5353
end
5454

5555
# Convert an `AbstractDict` to a `Bijection`
56-
function Bijection(dict::AbstractDict{S, T}) where S where T
56+
function Bijection(dict::AbstractDict{S,T}) where {S,T}
57+
vals = values(dict)
58+
if length(dict) != length(unique(vals))
59+
error("Repeated value found in dict")
60+
end
61+
5762
b = Bijection{S,T}()
5863
for (k, v) in pairs(dict)
5964
b[k] = v
6065
end
6166
return b
6267
end
63-
Bijection(b::Bijection) = b
68+
69+
# Copy constructor
70+
Bijection(b::Bijection) = Bijection(collect(b))
6471

6572
## Convert a list of pairs to a Bijection
6673
function Bijection(pair_list::Vector{Pair{S,T}}) where {S,T}
67-
d = Dict{S,T}(pair_list)
68-
Bijection(d)
74+
p = unique(pair_list) # remove duplicate pairs
75+
n = length(p)
76+
77+
xs = first.(p)
78+
ys = last.(p)
79+
if length(xs) != length(unique(xs)) || length(ys) != length(unique(ys))
80+
error("Repeated key or value found in pair list")
81+
end
82+
83+
b = Bijection{S,T}()
84+
for xy in p
85+
x, y = xy
86+
b[x] = y
87+
end
88+
return b
6989
end
7090

7191
# Decent way to print out a bijection
72-
function show(io::IO,b::Bijection{S,T}) where {S,T}
73-
print(io,"Bijection{$S,$T} (with $(length(b)) pairs)")
92+
function show(io::IO, b::Bijection{S,T}) where {S,T}
93+
print(io, "Bijection{$S,$T} (with $(length(b)) pairs)")
7494
end
7595

7696
display(b::Bijection) = (print("Bijection "); display(b.f))
@@ -84,11 +104,11 @@ display(b::Bijection) = (print("Bijection "); display(b.f))
84104
For a `Bijection` `b` use the syntax `b[x]=y` to add `(x,y)` to `b`.
85105
"""
86106
function setindex!(b::Bijection, y, x)
87-
if in(x,b.domain) || in(y,b.range)
107+
if in(x, b.domain) || in(y, b.range)
88108
error("One of x or y already in this Bijection")
89109
else
90-
push!(b.domain,x)
91-
push!(b.range,y)
110+
push!(b.domain, x)
111+
push!(b.range, y)
92112
b.f[x] = y
93113
b.finv[y] = x
94114
end
@@ -114,17 +134,17 @@ function inverse(b::Bijection, y)
114134
end
115135

116136
# the notation b(y) is a shortcut for inverse(b,y)
117-
(b::Bijection)(y) = inverse(b,y)
137+
(b::Bijection)(y) = inverse(b, y)
118138

119139

120140
# Remove a pair (x,y) from a bijection
121141
"""
122-
`delete!(b::Bijection,x)` deletes the ordered pair `(x,b[x])` from `b`.
142+
`delete!(b::Bijection,x)` deletes the ordered pair `(x,b[x])` from `b`.1==
123143
"""
124144
function delete!(b::Bijection, x)
125145
y = b[x]
126-
delete!(b.domain,x)
127-
delete!(b.range,y)
146+
delete!(b.domain, x)
147+
delete!(b.range, y)
128148
delete!(b.f, x)
129149
delete!(b.finv, y)
130150
return b
@@ -163,7 +183,7 @@ domain(b::Bijection) = copy(b.domain)
163183
image(b::Bijection) = copy(b.range)
164184

165185

166-
iterate(b::Bijection{S,T},s::Int) where {S,T} = iterate(b.f,s)
186+
iterate(b::Bijection{S,T}, s::Int) where {S,T} = iterate(b.f, s)
167187
iterate(b::Bijection{S,T}) where {S,T} = iterate(b.f)
168188

169189
# convert a Bijection into a Dict; probably not useful

0 commit comments

Comments
 (0)