Skip to content

Commit 9c2b5f9

Browse files
committed
table_format
1 parent 01e3d33 commit 9c2b5f9

File tree

3 files changed

+23
-315
lines changed

3 files changed

+23
-315
lines changed

src/components_utils/table_format.jl

Lines changed: 19 additions & 313 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
module TableFormat
2+
using JSON3
23
export Format, Align, Group, Padding, Prefix, Scheme, Sign, DSymbol, Trim
34

45
struct NamedValue{Name, T}
@@ -113,7 +114,7 @@ module TableFormat
113114
group_delimiter = nothing,
114115
groups = nothing,
115116

116-
nully = nothing,
117+
nully = "",
117118

118119
si_prefix = Prefix.none
119120
)
@@ -310,321 +311,26 @@ module TableFormat
310311
f.specifier[:type]
311312
)
312313
return JSON3.write(
313-
locale = deepcopy(f.locale),
314-
nully = f.nully,
315-
prefix = f.prefix,
316-
specifier = String(take!(spec_io))
317-
)
318-
end
319-
320-
321-
#=struct Format
322-
align ::Union{typeof(Align), Nothing}
323-
fill ::Union{Char, Nothing}
324-
group ::Union{typeof(Group), Bool, Nothing}
325-
padding ::Union{typeof(Padding), Bool, Nothing}
326-
padding_width ::Union{Integer, Nothing}
327-
precision ::Union{Integer, Nothing}
328-
scheme ::Union{typeof(Scheme), }
329-
sign,
330-
symbol,
331-
trim,
332-
333-
#locale
334-
symbol_prefix,
335-
symbol_suffix,
336-
decimal_delimiter,
337-
group_delimiter,
338-
groups,
339-
340-
#Nully
341-
nully,
342-
#Prefix
343-
si_prefix
344-
function Format(;
345-
locale = (),
346-
nully = "",
347-
prefix = Prefix.none,
348-
align = Align.default,
349-
fill = "",
350-
group = Group.no,
351-
width = "",
352-
padding = Padding.no,
353-
precision = "",
354-
sign = Sign.default,
355-
symbol = Symbol.no,
356-
trim = Trim.no,
357-
type = Scheme.default
358-
)
359-
return new(
360-
locale,
361-
nully,
362-
prefix,
363-
(
364-
align = align,
365-
fill = fill,
366-
group = group,
367-
width = width,
368-
padding = padding,
369-
precision = precision,
370-
sign = sign,
371-
symbol = symbol,
372-
trim = trim,
373-
type = type
374-
)
314+
(
315+
locale = deepcopy(f.locale),
316+
nully = f.nully,
317+
prefix = f.prefix,
318+
specifier = String(take!(spec_io))
375319
)
376-
end
320+
)
377321
end
378322

379-
function format(;
380-
align,
381-
fill,
382-
group,
383-
padding,
384-
padding_width,
385-
precision,
386-
scheme,
387-
sign,
388-
symbol,
389-
trim,
390-
391-
#locale
392-
symbol_prefix,
393-
symbol_suffix,
394-
decimal_delimiter,
395-
group_delimiter,
396-
groups,
397-
398-
#Nully
399-
nully,
400-
#Prefix
401-
si_prefix
323+
money(decimals, sign = Sign.default) = Format(
324+
group=Group.yes,
325+
precision=decimals,
326+
scheme=Scheme.fixed,
327+
sign=sign,
328+
symbol=Symbol.yes
402329
)
403-
end=#
404-
end
405-
#=
406-
import collections
407-
408-
409-
410-
411-
Trim = get_named_tuple("trim", {"no": "", "yes": "~"})
412-
413-
414-
class Format:
415-
def __init__(self, **kwargs):
416-
self._locale = {}
417-
self._nully = ""
418-
self._prefix = Prefix.none
419-
self._specifier = {
420-
"align": Align.default,
421-
"fill": "",
422-
"group": Group.no,
423-
"width": "",
424-
"padding": Padding.no,
425-
"precision": "",
426-
"sign": Sign.default,
427-
"symbol": Symbol.no,
428-
"trim": Trim.no,
429-
"type": Scheme.default,
430-
}
431-
432-
valid_methods = [
433-
m for m in dir(self.__class__) if m[0] != "_" and m != "to_plotly_json"
434-
]
435-
436-
for kw, val in kwargs.items():
437-
if kw not in valid_methods:
438-
raise TypeError(
439-
"{0} is not a format method. Expected one of".format(kw),
440-
str(list(valid_methods)),
441-
)
442-
443-
getattr(self, kw)(val)
444-
445-
def _validate_char(self, value):
446-
self._validate_string(value)
447-
448-
if len(value) != 1:
449-
raise ValueError("expected value to a string of length one")
450-
451-
def _validate_non_negative_integer_or_none(self, value):
452-
if value is None:
453-
return
454-
455-
if not isinstance(value, int):
456-
raise TypeError("expected value to be an integer")
457-
458-
if value < 0:
459-
raise ValueError("expected value to be non-negative", str(value))
460-
461-
def _validate_named(self, value, named_values):
462-
if value not in named_values:
463-
raise TypeError("expected value to be one of", str(list(named_values)))
464-
465-
def _validate_string(self, value):
466-
if not isinstance(value, (str, u"".__class__)):
467-
raise TypeError("expected value to be a string")
468-
469-
# Specifier
470-
def align(self, value):
471-
self._validate_named(value, Align)
472-
473-
self._specifier["align"] = value
474-
return self
475-
476-
def fill(self, value):
477-
self._validate_char(value)
478-
479-
self._specifier["fill"] = value
480-
return self
481-
482-
def group(self, value):
483-
if isinstance(value, bool):
484-
value = Group.yes if value else Group.no
485-
486-
self._validate_named(value, Group)
487-
488-
self._specifier["group"] = value
489-
return self
490-
491-
def padding(self, value):
492-
if isinstance(value, bool):
493-
value = Padding.yes if value else Padding.no
494330

495-
self._validate_named(value, Padding)
496331

497-
self._specifier["padding"] = value
498-
return self
499-
500-
def padding_width(self, value):
501-
self._validate_non_negative_integer_or_none(value)
502-
503-
self._specifier["width"] = value if value is not None else ""
504-
return self
505-
506-
def precision(self, value):
507-
self._validate_non_negative_integer_or_none(value)
508-
509-
self._specifier["precision"] = ".{0}".format(value) if value is not None else ""
510-
return self
511-
512-
def scheme(self, value):
513-
self._validate_named(value, Scheme)
514-
515-
self._specifier["type"] = value
516-
return self
517-
518-
def sign(self, value):
519-
self._validate_named(value, Sign)
520-
521-
self._specifier["sign"] = value
522-
return self
523-
524-
def symbol(self, value):
525-
self._validate_named(value, Symbol)
526-
527-
self._specifier["symbol"] = value
528-
return self
529-
530-
def trim(self, value):
531-
if isinstance(value, bool):
532-
value = Trim.yes if value else Trim.no
533-
534-
self._validate_named(value, Trim)
535-
536-
self._specifier["trim"] = value
537-
return self
538-
539-
# Locale
540-
def symbol_prefix(self, value):
541-
self._validate_string(value)
542-
543-
if "symbol" not in self._locale:
544-
self._locale["symbol"] = [value, ""]
545-
else:
546-
self._locale["symbol"][0] = value
547-
548-
return self
549-
550-
def symbol_suffix(self, value):
551-
self._validate_string(value)
552-
553-
if "symbol" not in self._locale:
554-
self._locale["symbol"] = ["", value]
555-
else:
556-
self._locale["symbol"][1] = value
557-
558-
return self
559-
560-
def decimal_delimiter(self, value):
561-
self._validate_char(value)
562-
563-
self._locale["decimal"] = value
564-
return self
565-
566-
def group_delimiter(self, value):
567-
self._validate_char(value)
568-
569-
self._locale["group"] = value
570-
return self
571-
572-
def groups(self, groups):
573-
groups = (
574-
groups
575-
if isinstance(groups, list)
576-
else [groups]
577-
if isinstance(groups, int)
578-
else None
579-
)
580-
581-
if not isinstance(groups, list):
582-
raise TypeError("expected groups to be an integer or a list of integers")
583-
if len(groups) == 0:
584-
raise ValueError(
585-
"expected groups to be an integer or a list of " "one or more integers"
586-
)
587-
588-
for group in groups:
589-
if not isinstance(group, int):
590-
raise TypeError("expected entry to be an integer")
591-
592-
if group <= 0:
593-
raise ValueError("expected entry to be a non-negative integer")
594-
595-
self._locale["grouping"] = groups
596-
return self
597-
598-
# Nully
599-
def nully(self, value):
600-
self._nully = value
601-
return self
602-
603-
# Prefix
604-
def si_prefix(self, value):
605-
self._validate_named(value, Prefix)
606-
self._prefix = value
607-
return self
608-
609-
def to_plotly_json(self):
610-
f = {}
611-
f["locale"] = self._locale.copy()
612-
f["nully"] = self._nully
613-
f["prefix"] = self._prefix
614-
aligned = self._specifier["align"] != Align.default
615-
f["specifier"] = "{}{}{}{}{}{}{}{}{}{}".format(
616-
self._specifier["fill"] if aligned else "",
617-
self._specifier["align"],
618-
self._specifier["sign"],
619-
self._specifier["symbol"],
620-
self._specifier["padding"],
621-
self._specifier["width"],
622-
self._specifier["group"],
623-
self._specifier["precision"],
624-
self._specifier["trim"],
625-
self._specifier["type"],
626-
)
627-
628-
return f
629-
630-
=#
332+
function percentage(decimals, rounded::Bool=false)
333+
scheme = rounded ? Scheme.percentage_rounded : Scheme.percentage
334+
return Format(scheme = scheme, precision = decimals)
335+
end
336+
end

test/runtests.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#=include("env.jl")
1+
include("env.jl")
22
include("resources.jl")
33
include("devtools.jl")
44
include("dash_creation.jl")
@@ -9,6 +9,6 @@ include("context.jl")
99
include("core.jl")
1010
include("misc.jl")
1111
include("callbacks.jl")
12-
include("components_utils.jl")=#
12+
include("components_utils.jl")
1313
include("table_format.jl")
1414
#include("dev.jl")

test/table_format.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using Test
22
using Dash
33
using Dash.TableFormat
4+
import JSON3
45
@testset "named values" begin
56
@test TableFormat.Align.left.value == "<"
67
a = TableFormat.Align.default
@@ -172,4 +173,5 @@ end
172173
@test f.locale[:decimal] == ";"
173174
@test f.locale[:group] == ","
174175
@test f.locale[:grouping] == [2,2]
176+
175177
end

0 commit comments

Comments
 (0)