From a608c65206451141db9dd9cae8961705a61bb8bd Mon Sep 17 00:00:00 2001 From: "Pavel V. Dimens" Date: Tue, 26 May 2020 12:29:46 -0500 Subject: [PATCH 1/2] more flexible + better benchmarking + Julia 1.x compliant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR uses the convert_coord() function in pdimens/PopGen.jl to make ten() faster and more flexible. Flexible in the sense that it can tolerate cardinal directions as well, such as "11 32 42S". Before: julia> @btime ten("-10 26") 2.135 μs (33 allocations: 1.52 KiB)-10.433333333333334 julia> @btime ten("-10 26") 1.571 μs (18 allocations: 928 bytes)-10.433333333333334 --- src/ten.jl | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/src/ten.jl b/src/ten.jl index 2c303a4..2a59380 100644 --- a/src/ten.jl +++ b/src/ten.jl @@ -11,15 +11,22 @@ ten(d::Real, m::Real=0, s::Real=0) = # TODO: improve performance, if possible. There are a couple of slow tests to # make parsing of the string work. function ten(strng::AbstractString) - # Convert strings into numbers, empty strings into 0s. - # Replace in the string multiple spaces or colons with a single space, strip leading - # whitespaces, and split the resulting string using the space as separator. - tmp = map(x-> x=="" ? 0.0 : parse(Float64, x), - split(lstrip(replace(strng, r"(\:| )+" => s" ")), " ")) - # Concatenate "tmp" with 3 zeros, so that "angle" has at least 3 elements - # also with an empty string in input. - angle = vcat(tmp, zeros(Float64, 3))::Vector{Float64} - ten(angle[1], angle[2], angle[3]) + lowercase(coordinate) == "missing" && return missing + coord_strip = replace(uppercase(coordinate), r"[NSEW]" => "") + split_coord = parse.(Float32, split(coord_strip, r"\s|:")) + split_coord[2] /=60.0 + if length(split_coord) == 3 + split_coord[3] /=3600.0 + end + conv = sum(abs.(split_coord)) + # N + E are positive | S + W are negative + if split_coord[1] < 0 || occursin(r"[SW]", uppercase(coordinate)) + # negative + return conv * -1 + else + # positive + return conv + end end ten(itr) = ten(itr...) @@ -45,6 +52,12 @@ iterable like `(deg, min, sec)` or `[deg, min, sec]` is accepted as argument. If minutes and seconds are not specified they default to zero. +### Formatting requirements +- Coordinates as a `String` separated by spaces (`"11 43 41"`) or colons (`"11:43:41"`) +- Must use negative sign (`"-11 43.52"`) or single-letter cardinal direction (`"11 43.52W"`) +- Missing data should be coded as the string `"missing"` (can be accomplished with `replace!()`) +- Can mix colons and spaces (although it's bad practice + ### Output ### The decimal conversion of the sexagesimal numbers provided is returned. From 46549086ce30b8c530c266ff3f85cb9611c0050c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mos=C3=A8=20Giordano?= Date: Sat, 27 Jun 2020 20:25:40 +0100 Subject: [PATCH 2/2] Update src/ten.jl --- src/ten.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ten.jl b/src/ten.jl index 2a59380..fa6c6fd 100644 --- a/src/ten.jl +++ b/src/ten.jl @@ -10,7 +10,7 @@ ten(d::Real, m::Real=0, s::Real=0) = # TODO: improve performance, if possible. There are a couple of slow tests to # make parsing of the string work. -function ten(strng::AbstractString) +function ten(coordinate::AbstractString) lowercase(coordinate) == "missing" && return missing coord_strip = replace(uppercase(coordinate), r"[NSEW]" => "") split_coord = parse.(Float32, split(coord_strip, r"\s|:"))