Skip to content

Commit

Permalink
fixes Humanizr#348
Browse files Browse the repository at this point in the history
  • Loading branch information
davidceto1 committed Aug 15, 2018
1 parent 604ebcc commit 82894c7
Show file tree
Hide file tree
Showing 10 changed files with 213 additions and 1 deletion.
25 changes: 25 additions & 0 deletions src/Humanizer.Tests/WordsToNumberTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xunit;

namespace Humanizer.Tests
{
[UseCulture("en-US")]
public class WordsToNumberTest
{
[InlineData("one", 1)]
[InlineData("minus five", -5)]
[InlineData("eleven", 11)]
[InlineData("ninety five", 95)]
[InlineData("hundred five", 105)]
[InlineData("one hundred ninety six", 196)]
[Theory]
public void ToNumber(string words, int expectedNumber)
{
Assert.Equal(expectedNumber, words.ToNumber());
}
}
}
18 changes: 18 additions & 0 deletions src/Humanizer.sln
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "NuSpecs", "NuSpecs", "{AA44
..\NuSpecs\Humanizer.nuspec = ..\NuSpecs\Humanizer.nuspec
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConsoleApp1", "ConsoleApp1\ConsoleApp1.csproj", "{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
Humanizer.Tests.Shared\Humanizer.Tests.Shared.projitems*{f886a8da-3efc-4a89-91dd-06faf13da172}*SharedItemsImports = 4
Expand Down Expand Up @@ -128,6 +130,22 @@ Global
{511A7984-F455-4A6E-ADB9-9CAAC47EA079}.Release|x64.Build.0 = Release|Any CPU
{511A7984-F455-4A6E-ADB9-9CAAC47EA079}.Release|x86.ActiveCfg = Release|Any CPU
{511A7984-F455-4A6E-ADB9-9CAAC47EA079}.Release|x86.Build.0 = Release|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Debug|ARM.ActiveCfg = Debug|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Debug|ARM.Build.0 = Debug|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Debug|x64.ActiveCfg = Debug|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Debug|x64.Build.0 = Debug|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Debug|x86.ActiveCfg = Debug|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Debug|x86.Build.0 = Debug|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Release|Any CPU.Build.0 = Release|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Release|ARM.ActiveCfg = Release|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Release|ARM.Build.0 = Release|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Release|x64.ActiveCfg = Release|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Release|x64.Build.0 = Release|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Release|x86.ActiveCfg = Release|Any CPU
{4F3AF670-463C-4C9D-89B0-F569ECD4D5B9}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
19 changes: 18 additions & 1 deletion src/Humanizer/Configuration/Configurator.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Globalization;
using System.Reflection;
using Humanizer.DateTimeHumanizeStrategy;
Expand Down Expand Up @@ -35,6 +35,9 @@ public static LocaliserRegistry<IFormatter> Formatters
}

private static readonly LocaliserRegistry<INumberToWordsConverter> _numberToWordsConverters = new NumberToWordsConverterRegistry();

private static readonly LocaliserRegistry<IWordsToNumberConverter> _wordsToNumberConverters = new WordsToNumberConverterRegistry();

/// <summary>
/// A registry of number to words converters used to localise ToWords and ToOrdinalWords methods
/// </summary>
Expand All @@ -43,6 +46,11 @@ public static LocaliserRegistry<INumberToWordsConverter> NumberToWordsConverters
get { return _numberToWordsConverters; }
}

public static LocaliserRegistry<IWordsToNumberConverter> WordsToNumberConverters
{
get { return _wordsToNumberConverters; }
}

private static readonly LocaliserRegistry<IOrdinalizer> _ordinalizers = new OrdinalizerRegistry();
/// <summary>
/// A registry of ordinalizers used to localise Ordinalize method
Expand Down Expand Up @@ -87,6 +95,11 @@ internal static INumberToWordsConverter GetNumberToWordsConverter(CultureInfo cu
return NumberToWordsConverters.ResolveForCulture(culture);
}

internal static IWordsToNumberConverter GetWordsToNumberConverter(CultureInfo culture)
{
return WordsToNumberConverters.ResolveForCulture(culture);
}

/// <summary>
/// The ordinalizer to be used
/// </summary>
Expand Down Expand Up @@ -131,6 +144,8 @@ public static IDateTimeOffsetHumanizeStrategy DateTimeOffsetHumanizeStrategy

private static readonly Func<PropertyInfo, bool> DefaultEnumDescriptionPropertyLocator = p => p.Name == "Description";
private static Func<PropertyInfo, bool> _enumDescriptionPropertyLocator = DefaultEnumDescriptionPropertyLocator;


/// <summary>
/// A predicate function for description property of attribute to use for Enum.Humanize
/// </summary>
Expand All @@ -139,5 +154,7 @@ public static Func<PropertyInfo, bool> EnumDescriptionPropertyLocator
get { return _enumDescriptionPropertyLocator; }
set { _enumDescriptionPropertyLocator = value ?? DefaultEnumDescriptionPropertyLocator; }
}


}
}
20 changes: 20 additions & 0 deletions src/Humanizer/Configuration/DefaultWordsToNumberConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using System.Globalization;
using Humanizer.Localisation.WordsToNumber;

namespace Humanizer.Configuration
{
internal class DefaultWordsToNumberConverter : GenderlessWordsToNumberConverter
{
private readonly CultureInfo _culture;

public DefaultWordsToNumberConverter(CultureInfo culture)
{
_culture = culture;
}

public override int Convert(string words)
{
return words.ToNumber(_culture);
}
}
}
7 changes: 7 additions & 0 deletions src/Humanizer/Configuration/IWordsToNumberConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Humanizer.Configuration
{
public interface IWordsToNumberConverter
{
int Convert(string words);
}
}
13 changes: 13 additions & 0 deletions src/Humanizer/Configuration/WordsToNumberConverterRegistry.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using Humanizer.Localisation.WordsToNumber;

namespace Humanizer.Configuration
{
internal class WordsToNumberConverterRegistry : LocaliserRegistry<IWordsToNumberConverter>
{
public WordsToNumberConverterRegistry()
: base((culture) => new DefaultWordsToNumberConverter(culture))
{
Register("en", new EnglishWordsToNumberConverter());
}
}
}
3 changes: 3 additions & 0 deletions src/Humanizer/Humanizer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,8 @@
<SignAssembly>true</SignAssembly>
<AssemblyOriginatorKeyFile>Humanizer.snk</AssemblyOriginatorKeyFile>
<DebugType Condition=" '$(BuildingForLiveUnitTesting)' != 'true' ">embedded</DebugType>
<ApplicationIcon />
<OutputType>Library</OutputType>
<StartupObject />
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using System;
using System.Collections.Generic;
using Humanizer.Configuration;

namespace Humanizer.Localisation.WordsToNumber
{
internal class EnglishWordsToNumberConverter : GenderlessWordsToNumberConverter
{
private static readonly Dictionary<string, int> NumbersMap = new Dictionary<string, int>
{
{"zero",0},
{"one",1},
{"two",2},
{"three",3},
{"four",4},
{"five",5},
{"six",6},
{"seven",7},
{"eight",8},
{"nine",9},
{"ten",10},
{"eleven",11},
{"twelve",12},
{"thirteen",13},
{"fourteen",14},
{"fifteen",15},
{"sixteen",16},
{"seventeen",17},
{"eighteen",18},
{"nineteen",19},
{"twenty", 20 },
{"thirty", 30 },
{"forty", 40 },
{"fifty", 50 },
{"sixty", 60 },
{"seventy", 70 },
{"eighty", 80 },
{"ninety", 90 },
{"hundred", 100 },
{"thousand", 1000 },
{"million", 1000000 },
{"billion", 1000000000 }
};

public override int Convert(string words)
{
bool isNegative = false;
if (words.StartsWith("minus"))
{
isNegative = true;
words = words.Remove(0, 6);
}

string[] wordsArray = words.Split(' ');

int response = NumbersMap[wordsArray[0]];

for (int i = 1; i < wordsArray.Length; i++)
{
if(response < NumbersMap[wordsArray[i]])
{
response *= NumbersMap[wordsArray[i]];
}
else
{
response += NumbersMap[wordsArray[i]];
}

}

if(isNegative)
{
return response*-1;
}
else
{
return response;
}


}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Humanizer.Configuration;

namespace Humanizer.Localisation.WordsToNumber
{
internal abstract class GenderlessWordsToNumberConverter : IWordsToNumberConverter
{
public abstract int Convert(string words);
}
}
17 changes: 17 additions & 0 deletions src/Humanizer/WordsToNumberExtension.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Globalization;
using Humanizer.Configuration;

namespace Humanizer
{
/// <summary>
/// Transform humanized string to number; e.g. one => 1
/// </summary>
public static class WordsToNumberExtension
{
public static int ToNumber(this string words, CultureInfo culture = null)
{
return Configurator.GetWordsToNumberConverter(culture).Convert(words);
}

}
}

0 comments on commit 82894c7

Please sign in to comment.