Repository navigation
[wip]Introduce rbs and add a type definition file for processing.rb first
#56
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
Merged
Merged
Changes from all commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
3e2ab12
feat: add necessary gems to introduce rbs to this repository
ericgpks 674daa8
feat: add Steepfile with the minimum configuration
ericgpks 448c1e9
feat: add processing.rbs as a type definition file for processing.rb
ericgpks 764fb97
fix: add condition for using steep and typeprof to pass CI with all R…
ericgpks a6b60e6
Merge remote-tracking branch 'origin/main' into feat/introduce_rbs
kojix2 484656d
Rename Processing helper to Aggregation
kojix2 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| D = Steep::Diagnostic | ||
|
|
||
| target :lib do | ||
| signature "sig" | ||
| check "lib" # Directory name to check | ||
|
|
||
| configure_code_diagnostics(D::Ruby.silent) # `silent` diagnostics setting | ||
|
kojix2 marked this conversation as resolved.
|
||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,140 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| module YouPlot | ||
| module Aggregation | ||
| module_function | ||
|
|
||
| def count_values(arr, tally: true, reverse: false) | ||
| # tally was added in Ruby 2.7 | ||
| result = \ | ||
| if tally && Enumerable.method_defined?(:tally) | ||
| arr.tally | ||
| else | ||
| # value_counts Enumerable::Statistics | ||
| arr.value_counts(dropna: false) | ||
| end | ||
|
|
||
| sort_cache = {} | ||
|
|
||
| # sorting | ||
| result = result.sort do |a, b| | ||
| # compare values | ||
| r = b[1] <=> a[1] | ||
| # If the values are the same, compare by name | ||
| r = natural_compare(a[0], b[0], sort_cache) if r.zero? | ||
| r | ||
| end | ||
|
|
||
| # --reverse option | ||
| result.reverse! if reverse | ||
|
|
||
| # prepare for barplot | ||
| result.transpose | ||
| end | ||
|
|
||
| # Natural order comparison for tie-breaking when counts are equal. | ||
| # Fast paths handle text-only and pure numeric labels. | ||
| # Mixed labels still use chunked comparison (e.g. "chr1" vs "chr10"). | ||
| def natural_compare(a, b, cache = nil) | ||
| aa = natural_sort_key(a, cache) | ||
| bb = natural_sort_key(b, cache) | ||
|
|
||
| # Fast path: both labels are text-only, so plain string comparison is enough. | ||
| return aa[:string] <=> bb[:string] if aa[:type] == :text && bb[:type] == :text | ||
|
|
||
| # Fast path: both labels are pure numbers, so compare numerically first. | ||
| if aa[:type] == :numeric && bb[:type] == :numeric | ||
| r = aa[:numeric] <=> bb[:numeric] | ||
| return r unless r.zero? | ||
|
|
||
| # Tiebreaker for equivalent numeric values (e.g. "1" and "01") | ||
| return aa[:string] <=> bb[:string] | ||
| end | ||
|
|
||
| # Fallback path: at least one label mixes text and digits. | ||
| ta = ensure_natural_tokens(aa) | ||
| tb = ensure_natural_tokens(bb) | ||
| max = [ta.size, tb.size].max | ||
|
|
||
| 0.upto(max - 1) do |i| | ||
| xa = ta[i] | ||
| xb = tb[i] | ||
|
|
||
| return -1 if xa.nil? | ||
| return 1 if xb.nil? | ||
|
|
||
| r = if xa[0] == :num && xb[0] == :num | ||
| compare_integer_strings(xa[1], xb[1]) | ||
| else | ||
| xa[1] <=> xb[1] | ||
| end | ||
|
|
||
| return r unless r.zero? | ||
| end | ||
|
|
||
| aa[:string] <=> bb[:string] | ||
| end | ||
|
|
||
| # Classifies a value for natural sorting and caches the result per label. | ||
| def natural_sort_key(value, cache = nil) | ||
| str = value.to_s | ||
| return cache[str] if cache && cache.key?(str) | ||
|
|
||
| key = if str.match?(/\d/) | ||
| numeric = parse_numeric(str) | ||
| if numeric | ||
| # Pure numeric labels get a dedicated fast path. | ||
| { type: :numeric, string: str, numeric: numeric } | ||
| else | ||
| # Mixed labels fall back to chunked natural comparison. | ||
| { type: :mixed, string: str, tokens: nil } | ||
| end | ||
| else | ||
| # Text-only labels get a dedicated fast path. | ||
| { type: :text, string: str, tokens: nil } | ||
| end | ||
|
|
||
| cache ? cache[str] = key : key | ||
| end | ||
|
|
||
| # Memoizes token pairs for fallback chunked comparison. | ||
| def ensure_natural_tokens(key) | ||
| key[:tokens] ||= natural_tokens(key[:string]) | ||
| end | ||
|
|
||
| # Parses a string as a numeric value if it matches pure number format. | ||
| # Returns Float or nil. | ||
| def parse_numeric(str) | ||
| return nil unless str.match?(/\A[+-]?(?:\d+(?:\.\d+)?|\.\d+)\z/) | ||
|
|
||
| str.to_f | ||
| end | ||
|
|
||
| # Splits a string into [type, token] pairs for natural comparison. | ||
| # Type is :num for digit-only chunks, :text for anything else. | ||
| # E.g. "chr10" => [[:text, "chr"], [:num, "10"]] | ||
| def natural_tokens(str) | ||
| str.scan(/\d+|\D+/).map do |tok| | ||
| kind = tok.match?(/\A\d+\z/) ? :num : :text | ||
| [kind, tok] | ||
| end | ||
| end | ||
|
|
||
| # Compares two numeric strings, handling leading zeros. | ||
| # Order: by length (sans leading zeros), then numeric value, then original. | ||
| def compare_integer_strings(a, b) | ||
| aa = a.sub(/\A0+/, '') | ||
| bb = b.sub(/\A0+/, '') | ||
| aa = '0' if aa.empty? | ||
| bb = '0' if bb.empty? | ||
|
|
||
| r = aa.length <=> bb.length | ||
| return r unless r.zero? | ||
|
|
||
| r = aa <=> bb | ||
| return r unless r.zero? | ||
|
|
||
| a <=> b | ||
| end | ||
| end | ||
| end |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| module YouPlot | ||
| module Aggregation | ||
| def self.count_values: (Enumerable[untyped], ?tally: bool, ?reverse: bool) -> Array[Array[untyped]] | ||
| end | ||
| end |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.