mykewould / crutches Goto Github PK
View Code? Open in Web Editor NEWSome Elixir support
License: Other
Some Elixir support
License: Other
Doctest failed: got UndefinedFunctionError with message undefined function: Crutches.Integer.digits/1
code: Integer.digits(101)
Integer.digits/1 was taken from Elixir. It should be credited with the proper copyright notice.
I think we should also include the @doc in the function
@doc ~S"""
Formats the bytes in `number` into a more understandable representation (e.g.,
giving it 1500 yields 1.5 KB). This method is useful for reporting file sizes to
users. You can customize the format in the `options` Dict.
See `as_human` if you want to pretty-print a generic number.
# Options
* `:locale` - Sets the locale to be used for formatting (defaults to current locale).
* `:precision` - Sets the precision of the number (defaults to 3).
* `:significant` - If true, precision will be the # of significant_digits. If false, the # of fractional digits (defaults to true)
* `:separator` - Sets the separator between the fractional and integer digits (defaults to “.”).
* `:delimiter` - Sets the thousands delimiter (defaults to “”).
* `:strip_insignificant_zeros` - If true removes insignificant zeros after the decimal separator (defaults to true)
* `:prefix` - If :si formats the number using the SI prefix (defaults to :binary)
# Examples
iex> Number.as_human_size(123)
"123 Bytes"
iex> Number.as_human_size(1234)
"1.21 KB"
iex> Number.as_human_size(12345)
"12.1 KB"
iex> Number.as_human_size(1234567)
"1.18 MB"
iex> Number.as_human_size(1234567890)
"1.15 GB"
iex> Number.as_human_size(1234567890123)
"1.12 TB"
iex> Number.as_human_size(1234567, precision: 2)
"1.2 MB"
iex> Number.as_human_size(483989, precision: 2)
"470 KB"
iex> Number.as_human_size(1234567, precision: 2, separator: ',')
"1,2 MB"
iex> Number.as_human_size(1234567890123, precision: 5)
"1.1228 TB"
iex> Number.as_human_size(524288000, precision: 5)
"500 MB"
iex> Number.as_human_size!("abc")
** (ArithmeticError) bad input number
"""
What do you think guys? Is this change in the naming scheme for better or worse?
http://hexdocs.pm/crutches/ does not open.
place holder
Integration for internationalization.
Should we build a data structure based on Range
that consist in the uninion of n Range
s or is out of scope? Should this live in a different project? Could be another library for kickstarting people in the world of Elixir!
I think we should start thinking about internationalization. The porting of the NumberHelpers
module has given this issue a boost on priority. Otherwise, the number helpers are mostly useless outside of USA. I think that linguist could be really easy to integrate. But, on the other hand, I think that the less dependencies we have, the better. Thoughts?
Currently it return nil
. I think empty list would be better, as then you can pipe this function into ones in the Enum
module without having to pattern match on the return value to handle the possible fail case (nil
).
See https://travis-ci.org/mykewould/crutches/builds/191438234
On Elixir 1.4, the result of Number.as_rounded
is different from the result that earlier Elixir versions gave. These should all be consistent and of the old behaviour
I don't have time to work on this, currently; so this is up for grabs!
I found this gist that implements Elixir module inheritance/extension. Maybe this good functionality to provide (also seems to provide a way to alias modules like Crutches.List
to List
without shadowing the standard library).
The gist has one issue (it is marked as a todo): it doesn't provide something to override functions without changing all of those that call the overridden function. I don't know if this can be fixed without modifications to Elixir itself, but a lot of Elixir is defined in Elixir macros, so it might be doable.
Thoughts?
Convert ActiveSupport Array#to_formatted_s to Crutches List.to_formatted_s
# Extends <tt>Array#to_s</tt> to convert a collection of elements into a
# comma separated id list if <tt>:db</tt> argument is given as the format.
#
# Blog.all.to_formatted_s(:db) # => "1,2,3"
Hints to get started:
Additional resources:
List intro
List documentation
Right now I am unable to know what the aim of the project is unless I know about what ActiveSupport is.
Also, a description in the module doc should be added so it will appear in the docs
# Splits or iterates over the array in +number+ of groups, padding any
# remaining slots with +fill_with+ unless it is +false+.
#
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3) {|group| p group}
# ["1", "2", "3", "4"]
# ["5", "6", "7", nil]
# ["8", "9", "10", nil]
#
# %w(1 2 3 4 5 6 7 8 9 10).in_groups(3, ' ') {|group| p group}
# ["1", "2", "3", "4"]
# ["5", "6", "7", " "]
# ["8", "9", "10", " "]
#
# %w(1 2 3 4 5 6 7).in_groups(3, false) {|group| p group}
# ["1", "2", "3"]
# ["4", "5"]
# ["6", "7"]
Convert Array#in_groups => List.in_groups
Hints to get started:
Additional resources:
List intro
List documentation
# Check whether the integer is evenly divisible by the argument.
#
# 0.multiple_of?(0) # => true
# 6.multiple_of?(5) # => false
# 10.multiple_of?(2) # => true
Convert Integer#multiple_of? => Integer.multiple_of
Hints to get started:
Additional resources:
Integer intro
Integer documentation
since we have Integer.digits/1, I think we should have Integer.undigits/1
the @doc for Integer.digits/1 is missing and it could be copied from Elixir codebase
# Divides the array into one or more subarrays based on a delimiting +value+
# or the result of an optional block.
#
# [1, 2, 3, 4, 5].split(3) # => [[1, 2], [4, 5]]
# (1..10).to_a.split { |i| i % 3 == 0 } # => [[1, 2], [4, 5], [7, 8], [10]]
Convert Array#split => List.split
Hints to get started:
Additional resources:
List intro
List documentation
Convert ActiveSupport Array#to_sentence to Crutches List.to_sentence
# Converts the array to a comma-separated sentence where the last element is
# joined by the connector word.
#
# You can pass the following options to change the default behavior. If you
# pass an option key that doesn't exist in the list below, it will raise an
# <tt>ArgumentError</tt>.
#
# ==== Options
#
# * <tt>:words_connector</tt> - The sign or word used to join the elements
# in arrays with two or more elements (default: ", ").
# * <tt>:two_words_connector</tt> - The sign or word used to join the elements
# in arrays with two elements (default: " and ").
# * <tt>:last_word_connector</tt> - The sign or word used to join the last element
# in arrays with three or more elements (default: ", and ").
# * <tt>:locale</tt> - If +i18n+ is available, you can set a locale and use
# the connector options defined on the 'support.array' namespace in the
# corresponding dictionary file.
#
# ==== Examples
#
# [].to_sentence # => ""
# ['one'].to_sentence # => "one"
# ['one', 'two'].to_sentence # => "one and two"
# ['one', 'two', 'three'].to_sentence # => "one, two, and three"
#
# ['one', 'two'].to_sentence(passing: 'invalid option')
# # => ArgumentError: Unknown key :passing
#
# ['one', 'two'].to_sentence(two_words_connector: '-')
# # => "one-two"
#
# ['one', 'two', 'three'].to_sentence(words_connector: ' or ', last_word_connector: ' or at least ')
# # => "one or two or at least three"
#
# Using <tt>:locale</tt> option:
#
# # Given this locale dictionary:
# #
# # es:
# # support:
# # array:
# # words_connector: " o "
# # two_words_connector: " y "
# # last_word_connector: " o al menos "
#
# ['uno', 'dos'].to_sentence(locale: :es)
# # => "uno y dos"
#
# ['uno', 'dos', 'tres'].to_sentence(locale: :es)
# # => "uno o dos o al menos tres"
Hints to get started:
Additional resources:
List intro
List documentation
@doc ~S"""
Formats a `number` into a currency string (e.g., $13.65). You can customize the format in
the `options` hash. The `as_currency!` method raises an exception if the input is
not numeric
# Options
* `:locale` - Sets the locale to be used for formatting (defaults to current locale).
* `:precision` - Sets the level of precision (defaults to 2).
* `:unit` - Sets the denomination of the currency (defaults to “$”).
* `:separator` - Sets the separator between the units (defaults to “.”).
* `:delimiter` - Sets the thousands delimiter (defaults to “,”).
* `:format` - Sets the format for non-negative numbers (defaults to “%u%n”). Fields are %u for the currency, and %n for the number.
* `:negative_format` - Sets the format for negative numbers (defaults to prepending an hyphen to the formatted number given by :format). Accepts the same fields than :format, except %n is here the absolute value of the number.
# Examples
iex> Number.as_currency(1234567890.50)
"$1,234,567,890.50"
iex> Number.as_currency(1234567890.506)
"$1,234,567,890.51"
iex> Number.as_currency(1234567890.506, precision: 3)
"$1,234,567,890.506"
iex> Number.as_currency(1234567890.506, locale: :fr)
"1 234 567 890,51 €"
iex> Number.as_currency("123a456")
"$123a456"
iex> Number.as_currency!("123a456")
** (ArithmeticError) invalid number
iex> Number.as_currency(-1234567890.50, negative_format: "(%u%n)")
"($1,234,567,890.50)"
iex> Number.as_currency(1234567890.50, unit: "R$", separator: ",", delimiter: "")
"R$1234567890,50"
iex> Number.as_currency(1234567890.50, unit: "R$", separator: ",", delimiter: "", format: "%n %u")
"1234567890,50 R$"
"""
Elixir provides this functionality in get_in
and and update version with put_in
:
http://elixir-lang.org/docs/stable/elixir/Kernel.html#get_in/2
http://elixir-lang.org/docs/stable/elixir/Kernel.html#put_in/3
Truncates a given `text` after a given `length` if `text` is longer than `length`:
## Examples
iex> String.truncate("Once upon a time in a world far far away", 27)
"Once upon a time in a wo..."
iex> String.truncate("Once upon a time in a world far far away", 27, separator: " ")
"Once upon a time in a..."
iex> String.truncate("Once upon a time in a world far far away", 27, separator: ~r/\s/)
"Once upon a time in a..."
iex> String.truncate("And they found that many people were sleeping better.", 25, omission: "... (continued)")
"And they f... (continued)"
More information to come. Generated from #7.
Convert ActiveSupport Array#from to Crutches List.from
# Returns the tail of the array from +position+.
#
# %w( a b c d ).from(0) # => ["a", "b", "c", "d"]
# %w( a b c d ).from(2) # => ["c", "d"]
# %w( a b c d ).from(10) # => []
# %w().from(0) # => []
# %w( a b c d ).from(-2) # => ["c", "d"]
# %w( a b c ).from(-10) # => []
Hints to get started:
Additional resources:
List intro
List documentation
Convert ActiveSupport Array#to to Crutches List.to
# Returns the beginning of the array up to +position+.
#
# %w( a b c d ).to(0) # => ["a"]
# %w( a b c d ).to(2) # => ["a", "b", "c"]
# %w( a b c d ).to(10) # => ["a", "b", "c", "d"]
# %w().to(0) # => []
# %w( a b c d ).to(-2) # => ["a", "b", "c"]
# %w( a b c ).to(-10) # => []
Hints to get started:
Additional resources:
List intro
List documentation
The CLA at https://github.com/FLIF-hub/FLIF-CLAs has been signed by 3 people so far (as of 20151119).
There are 17 contributors so far (as of 20151119) to https://github.com/FLIF-hub/FLIF
One of the contributors is jonsneyers, so that means there are 13 other contributors who have contributed code to FLIF, yet have not signed the CLA.
This needs to be rectified as soon as possible, otherwise later re-licensing of the code from GPLv3 to any other license becomes extremely difficult or impossible.
@doc ~S"""
Formats a `number` as a percentage string (e.g., 65%). You can customize the
format in the `options` Dict
The `as_percentage!` method raises an error if the input is not numeric.
# Options
* `:locale` - Sets the locale to be used for formatting (defaults to current locale).
* `:precision` - Sets the precision of the number (defaults to 3).
* `:significant` - If true, precision will be the # of significant_digits. If false, the # of fractional digits (defaults to false).
* `:separator` - Sets the separator between the fractional and integer digits (defaults to “.”).
* `:delimiter` - Sets the thousands delimiter (defaults to “”).
* `:strip_insignificant_zeros` - If true removes insignificant zeros after the decimal separator (defaults to false).
* `:format` - Specifies the format of the percentage string The number field is %n (defaults to “%n%”).
# Examples
iex> Number.as_percentage(100)
"100.000%"
iex> Number.as_percentage("98")
"98.000%"
iex> Number.as_percentage(100, precision: 0)
"100%"
iex> Number.as_percentage(1000, delimiter: '.', separator: ',')
"1.000,000%"
iex> Number.as_percentage(302.24398923423, precision: 5)
"302.24399%"
iex> Number.as_percentage(1000, locale: :fr)
"1 000,000%"
iex> Number.as_percentage("98a")
"98a%"
iex> Number.as_percentage(100, format: "%n %")
"100 %"
iex> Number.as_percentage!("98a", raise: true)
** (ArithmeticError) bad input number
"""
It could be worthwhile to adopt CI to get some feedback on tests in PRs. In addition, we get some awesome badges :)
There are a couple of services that I like and work with Elixir projects:
Curious to hear thoughts and opinions. If any help is needed to set it all up, I'll gladly help.
1.1.0 is the latest version crutches supports. Can we upgrade to the latest and greatest?
# Returns a string that represents the array in XML by invoking +to_xml+
# on each element. Active Record collections delegate their representation
# in XML to this method.
#
# All elements are expected to respond to +to_xml+, if any of them does
# not then an exception is raised.
#
# The root node reflects the class name of the first element in plural
# if all elements belong to the same type and that's not Hash:
#
# customer.projects.to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <projects type="array">
# <project>
# <amount type="decimal">20000.0</amount>
# <customer-id type="integer">1567</customer-id>
# <deal-date type="date">2008-04-09</deal-date>
# ...
# </project>
# <project>
# <amount type="decimal">57230.0</amount>
# <customer-id type="integer">1567</customer-id>
# <deal-date type="date">2008-04-15</deal-date>
# ...
# </project>
# </projects>
#
# Otherwise the root element is "objects":
#
# [{ foo: 1, bar: 2}, { baz: 3}].to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <objects type="array">
# <object>
# <bar type="integer">2</bar>
# <foo type="integer">1</foo>
# </object>
# <object>
# <baz type="integer">3</baz>
# </object>
# </objects>
#
# If the collection is empty the root element is "nil-classes" by default:
#
# [].to_xml
#
# <?xml version="1.0" encoding="UTF-8"?>
# <nil-classes type="array"/>
#
# To ensure a meaningful root element use the <tt>:root</tt> option:
#
# customer_with_no_projects.projects.to_xml(root: 'projects')
#
# <?xml version="1.0" encoding="UTF-8"?>
# <projects type="array"/>
#
# By default name of the node for the children of root is <tt>root.singularize</tt>.
# You can change it with the <tt>:children</tt> option.
#
# The +options+ hash is passed downwards:
#
# Message.all.to_xml(skip_types: true)
#
# <?xml version="1.0" encoding="UTF-8"?>
# <messages>
# <message>
# <created-at>2008-03-07T09:58:18+01:00</created-at>
# <id>1</id>
# <name>1</name>
# <updated-at>2008-03-07T09:58:18+01:00</updated-at>
# <user-id>1</user-id>
# </message>
# </messages>
#
Convert ActiveSupport Array#to_xml to Crutches List.to_xml
Hints to get started:
Additional resources:
List intro
List documentation
XML resources for Elixir
Parsing Elixir
I was skimming through the docs, this one certainly called my attention.
to is generally used to convert data type from one type to another, such as in Enum.to_list/1, Float.to_string/1
I think Crutches.List.to/2 will make more sense to rename it Crutches.List.up_to/2
the thing is what are you gonna name "from".
personally I think having Enum.slice/3 there is not need to have such functions (and Enum will work with any enumerable, not just lists).
in a case you want to keep it , maybe Enum.slice_to Enum.slice_from would be more clear (but redundant IMO)
@doc ~S"""
Formats a `number` with the specified level of :precision (e.g., 112.32 has a
precision of 2 if `:significant` is false, and 5 if `:significant` is true). You
can customize the format in the `options` Dict.
# Options
* `:locale` - Sets the locale to be used for formatting (defaults to current locale).
* `:precision` - Sets the precision of the number (defaults to 3).
* `:significant` - If true, precision will be the # of significant_digits. If false, the # of fractional digits (defaults to false).
* `:separator` - Sets the separator between the fractional and integer digits (defaults to “.”).
* `:delimiter` - Sets the thousands delimiter (defaults to “”).
* `:strip_insignificant_zeros` - If true removes insignificant zeros after the decimal separator (defaults to false).
# Examples
iex> Number.as_rounded(111.2345)
"111.235"
iex> Number.as_rounded(111.2345, precision: 2)
"111.23"
iex> Number.as_rounded(13, precision: 5)
"13.00000"
iex> Number.as_rounded(389.32314, precision: 0)
"389"
iex> Number.as_rounded(111.2345, significant: true)
"111"
iex> Number.as_rounded(111.2345, precision: 1, significant: true)
"100"
iex> Number.as_rounded(13, precision: 5, significant: true)
"13.000"
iex> Number.as_rounded(111.234, locale: :fr)
"111,234"
iex> Number.as_rounded(13, precision: 5, significant: true, strip_insignificant_zeros: true)
"13"
iex> Number.as_rounded(389.32314, precision: 4, significant: true)
"389.3"
iex> Number.as_rounded(1111.2345, precision: 2, separator: ',', delimiter: '.')
"1.111,23"
"""
Convert ActiveSupport Array#without to Crutches List.without
# Returns a copy of the Array without the specified elements.
#
# people = ["David", "Rafael", "Aaron", "Todd"]
# people.without "Aaron", "Todd"
# => ["David", "Rafael"]
#
# Note: This is an optimization of `Enumerable#without` that uses `Array#-`
# instead of `Array#reject` for performance reasons.
Hints to get started:
Additional resources:
List intro
List documentation
Compare two ranges and see if they overlap each other
## Examples
iex> Range.overlaps?(1..5, 4..6)
true
iex> Range.overlaps?(1..5, 7..9)
false
PR #43 is now merged, which gives us some nicer functions to handle keyword options to functions, but we aren't out of the woods yet. There are a couple of locations in the library that aren't making use of the new functions in the Crutches.Option
module yet.
Here is a list:
Crutches.Format.Number.as_delimited/2
, see #57.Crutches.Format.Number.as_phone/2
Crutches.Format.Number.as_currency/2
Crutches.List.as_sentence/2
These need to be refactored to make use of the following convention (if possible):
@function_name [
valid: [:some, :option],
defaults: [
some: "foo",
option: "bar"
]
]
def function_name(args, opts \\ @function_name[:defaults])
def function_name(args, opts) do
# This validates and merges the options, throwing on error.
opts = Crutches.Option.combine!(opts, @function_name) # Or use Option.combine[!]/3
...
end
Tests (in general) shouldn't require modifications. Everyone is free to work on this, but I'm going to tackle the first one to provide an example.
In the meantime, if you find that a function cannot be changed to make use of this convention, please do post why. Might be because we are missing a use case in the Option
module and I'd like to know!
Not sure of the method naming convention but it would be nice if there's a way to check if a given number is a prime number.
iex(1)> Crutches.Format.Number.as_human 999_499
"999 Thousand"
iex(2)> Crutches.Format.Number.as_human 999_500
"1000 Thousand"
iex(3)> Crutches.Format.Number.as_human 999_999
"1000 Thousand"
iex(4)> Crutches.Format.Number.as_human 1_000_000
"1 Million"
iex(5)> Crutches.Format.Number.as_human 999_999_999
"1000 Million"
"1000 thousand" should probably be "1 million". Same with "1000 Million", "1000 Billion", etc.
FWIW, Rails/ActiveSupport had this same issue up until 2 months ago
More information to come. Generated form #7.
The whole module should be converted to the new format.
@doc ~S"""
Pretty prints (formats and approximates) a `number` in a way it is more readable
by humans (eg.: 1200000000 becomes “1.2 Billion”). This is useful for numbers
that can get very large (and too hard to read).
See `as_human_size` if you want to print a file size.
You can also define you own unit-quantifier names if you want to use other
decimal units (eg.: 1500 becomes “1.5 kilometers”, 0.150 becomes
“150 milliliters”, etc). You may define a wide range of unit quantifiers, even
fractional ones (centi, deci, mili, etc).
The `as_human!` method raises an exception if the input is not a valid
number
# Options
* `:locale` - Sets the locale to be used for formatting (defaults to current
locale).
* `:precision` - Sets the precision of the number (defaults to 3).
* `:significant` - If true, precision will be the # of significant_digits. If
false, the # of fractional digits (defaults to true)
* `:separator` - Sets the separator between the fractional and integer digits
(defaults to “.”).
* `:delimiter` - Sets the thousands delimiter (defaults to “”).
* `:strip_insignificant_zeros` - If true removes insignificant zeros after the
decimal separator (defaults to true)
* `:units` - A Hash of unit quantifier names. Or a string containing an i18n
scope where to find this hash. It might have the following keys:
+ `integers`: :unit, :ten, :hundred, :thousand, :million, :billion,
:trillion, :quadrillion
+ `fractionals`: :deci, :centi, :mili, :micro, :nano, :pico, :femto
* `:format` - Sets the format of the output string (defaults to “%n %u”).
The field types are:
+ %u - The quantifier (ex.: 'thousand')
+ %n - The number
# Examples
iex> Number.as_human(123)
"123"
iex> Number.as_human(1234)
"1.23 Thousand"
iex> Number.as_human(12345)
"12.3 Thousand"
iex> Number.as_human(1234567)
"1.23 Million"
iex> Number.as_human(1234567890)
"1.23 Billion"
iex> Number.as_human(1234567890123)
"1.23 Trillion"
iex> Number.as_human(1234567890123456)
"1.23 Quadrillion"
iex> Number.as_human(1234567890123456789)
"1230 Quadrillion"
iex> Number.as_human(489939, precision: 2)
"490 Thousand"
iex> Number.as_human(489939, precision: 4)
"489.9 Thousand"
iex> Number.as_human(1234567, precision: 4, significant: false)
"1.2346 Million"
iex> Number.as_human(1234567, precision: 1,separator: ',', significant: false)
"1,2 Million"
iex> Number.as_human(500000000, precision: 5)
"500 Million"
iex> Number.as_human(12345012345, significant: false)
"12.345 Billion"
iex> Number.as_human!("abc")
** (ArithmeticError) bad input number
"""
Hi, i just found out through the elixir mailing list about this project.
I have thought about something like this for a while, so kudos for creating something like this,
I have code to contribute, but before moving forward I would like to make a comment that can be taking into consideration.
Given the nature of the project, it is very likely that at some point some of the functions may end up making it into Elixir code base.
So i think to avoid conflicts in the future, it should be considered to release the code under a dual license, MIT/APACHE2, or maybe a public license.
I think if still be needed to release the rights to the elixir project if they want to be included as a special mention in the NOTICE file is unlikely to happen.
Maybe there's an easier solution, like anybody submitting code, agrees that it could potentially be added to Elixir project, maybe we could include the credits in the commit message when added to elixir.
As the idea of the project is to create kind of an Active Support migration. Would be nice to have a checklist of ActiveSupport features and what is already done. This will generate a better notion of the project status.
What do you think of this?
Currently, I'm seeing something along these lines a lot:
@function_name [
valid_options: [:some, :option],
default_options: [
some: "foo"
option: "bar"
]
]
def function_name(args, opts \\ @function_name[:default_options])
def function_name(args, opts) do
Crutches.Keyword.validate_keys!(opts, @function_name[:valid_options])
options = Keyword.merge(@function_name[:default_options], opts)
...
end
I think it would be nice if we instead could write something like this:
@function_name [
valid: [:some, :option],
defaults: [
some: "foo",
option: "bar"
]
]
def function_name(args, opts \\ @function_name[:defaults])
def function_name(args, opts) do
# This validates and merges the options, throwing on error.
opts = Crutches.Options.combine!(opts, @function_name)
...
end
It is less code to keep track of, it makes the intent more clear and is a bit less to type. I also think it is a better API.
I'll work on this if we end up liking this. Going to be lots of work and be a little invasive to adopt this everywhere.
What kind of variants seem to be good? I have thought of:
Options.combine!(options, configuration)
— throwingOptions.combine(options, configuration)
— non-throwingOptions.combine!(options, configuration, combinator)
— throwing, with custom combinator.Options.combine(options, configuration, combinator)
— non-throwing, with custom combinator.Anything else? Feedback welcome :)
Hey there.
I saw your post on reddit and this looks like a fun project to help with. I'm an Elixir newbie, but the easier issues seem like a great place to start. Seems like they're all being worked on though. Do you have more coming soon, or a suggestion for a missing feature?
@doc ~S"""
Checks a keyword list for unexpected keys, by using a default list of keys. When a bad key is detected it returns false, else it returns true.
## Examples
iex> Keyword.all_keys_valid?([good: "", good_opt: ".", bad: "!"], [:good, :good_opt])
false
iex> Keyword.all_keys_valid?([good: "", good_opt: "."], [:good, :good_opt])
true
"""
Hints to get started:
mix test
)Additional resources:
The bad_options_check where most functionality will reside
Keyword intro
Keyword documentation
Initial layout proposal for wiki design. Obviously we want it so that it covers enough information for a beginner to get started. I have no intentions of duplicating efforts around Elixir documentation, but there will be a links section for those who are totally new to the language. Most of the documentation will link to the code where the functions are described in more detail. The FAQ will outline some of the questions and concerns we've talked about in issues and PRs.
Feedback and thoughts always welcome!
Wiki Design (Very rough)
place holder
If you'd like to see something implemented into Crutches, please post it here. I'll do the leg work of writing up the documentation for the issue, I just need your ideas!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.