Skip to content

Commit

Permalink
Create
Browse files Browse the repository at this point in the history
  • Loading branch information
Heptazhou committed May 7, 2024
1 parent a313cda commit 39dad1f
Show file tree
Hide file tree
Showing 8 changed files with 239 additions and 0 deletions.
48 changes: 48 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
name: CI
on:
pull_request:
branches:
- "master"
push:
branches:
- "master"
tags:
- "*"
defaults:
run:
shell: bash
env:
JULIA_NUM_THREADS: auto
jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 30
strategy:
fail-fast: false
matrix:
os:
- windows-latest
- ubuntu-latest
- macos-latest
julia-version:
- "1.9"
- "1"
- "nightly"
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- uses: julia-actions/setup-julia@v2
with:
show-versioninfo: true
version: ${{ matrix.julia-version }}
- uses: julia-actions/julia-buildpkg@v1
with:
ignore-no-cache: true
- uses: julia-actions/julia-runtest@v1
- uses: heptazhou/julia-codecov@v1
with:
dirs: src:ext
- uses: codecov/[email protected]
with:
file: lcov.info
13 changes: 13 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,18 @@ uuid = "0b12d779-4123-4875-9d6c-e33c2e29e2c9"
authors = ["Heptazhou <zhou at 0h7z dot com>"]
version = "0.1.0"

[deps]
DelimitedFiles = "8bb1440f-4735-579b-a4ab-409b98df4dab"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"

[weakdeps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"

[extensions]
DataFramesExt = "DataFrames"
StatisticsExt = "StatsBase"

[compat]
julia = "≥ 1.9"
32 changes: 32 additions & 0 deletions ext/DataFramesExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (C) 2023-2024 Heptazhou <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

module DataFramesExt

using DataFrames: DataFrame
using DelimitedFiles: readdlm, writedlm

function Base.read(s::IOStream, ::Type{DataFrame})
t::NTuple{2, Matrix} = readdlm(s, header = true)
DataFrame(t[1], vec(t[2]))
end

function Base.write(s::IOStream, x::DataFrame)
writedlm(s, [propertynames(x)'; Matrix(x)])
filesize(s)
end

end # module

28 changes: 28 additions & 0 deletions ext/StatisticsExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (C) 2023-2024 Heptazhou <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

module StatisticsExt

using Exts: Exts
using StatsBase: AbstractWeights
using StatsBase: mean

function Exts.nanmean(A::AbstractArray, w::AbstractWeights; dims = :)
r = mean(A, (w); dims)
!isnan(r) ? (r) : (@assert all(iszero, w); mean(A; dims))
end

end # module

37 changes: 37 additions & 0 deletions src/BaseExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Copyright (C) 2018-2024 Heptazhou <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

module BaseExt

function Base.adjoint(m::T)::AbstractMatrix{Any} where T <: AbstractVecOrMat{Any}
permutedims(m)
end
function Base.adjoint(m::T)::AbstractMatrix{<:Symbol} where T <: AbstractVecOrMat{<:Symbol}
permutedims(m)
end
function Base.adjoint(m::T)::AbstractMatrix{<:AbstractChar} where T <: AbstractVecOrMat{<:AbstractChar}
permutedims(m)
end
function Base.adjoint(m::T)::AbstractMatrix{<:AbstractString} where T <: AbstractVecOrMat{<:AbstractString}
permutedims(m)
end

function Base.log10(x::T, σ::T) where T <: Real
# https://physics.stackexchange.com/q/95254
log10(x), σ / log(10)x
end

end # module

32 changes: 32 additions & 0 deletions src/Exts.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,36 @@
# Copyright (C) 2023-2024 Heptazhou <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

module Exts

export invsqrt
export nanmean

using Reexport: @reexport

@reexport using Base.Iterators: map as lmap
@reexport using Base.Threads: @spawn, @threads, nthreads

include("BaseExt.jl")

function invsqrt(x::T) where T <: Real
F::Type = float(T)
F(big(x) |> inv |> sqrt)
end

function nanmean end

end # module

4 changes: 4 additions & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[deps]
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
45 changes: 45 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Copyright (C) 2024 Heptazhou <[email protected]>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

using Test

@testset "BaseExt" begin
@test_throws MethodError log10(11, 2)
@test_throws MethodError repr([:a, 1]')
@test_throws UndefVarError invsqrt(1.0)
using Exts

@test [:_ -1] == [:_, -1]'
@test [:p :q] == [:p, :q]'
@test ['1' '2'] == ['1', '2']'
@test ["x" "y"] == ["x", "y"]'
@test invsqrt(2^-2) == 2
@test_nowarn log10(11, 2)
end

@testset "DataFramesExt" begin
using DataFrames: DataFrame
df = DataFrame(rand(Int16, (8, 2)), :auto)
tmp = tempname()
@test_nowarn write(tmp, df)
@test read(tmp, DataFrame) == df
end

@testset "StatisticsExt" begin
using StatsBase: mean, weights
@test mean(1:20, weights(zeros(20))) |> isnan
@test mean(1:20) === nanmean(1:20, weights(zeros(20)))
end

0 comments on commit 39dad1f

Please sign in to comment.