Skip to content

Commit

Permalink
Ajout des variables
Browse files Browse the repository at this point in the history
  • Loading branch information
FaustVX committed Oct 14, 2013
1 parent e5a8541 commit f079302
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 14 deletions.
11 changes: 10 additions & 1 deletion MathString.Test/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,21 @@ class Program
{
static void Main(string[] args)
{
MathString.AddGlobalVariable(new MathString.Variable("plop", 5));
MathString m = new MathString();
string line;
while ((line = Console.ReadLine()) != "")
{
string formule = line;
Console.WriteLine("\"{0}\" = {1}", formule, m.Convert(formule));
try
{
string result = m.Convert(formule);
Console.WriteLine("\"{0}\" = {1}", formule, result);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
}
Expand Down
16 changes: 16 additions & 0 deletions MathString.sln
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,36 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathString", "MathString\Ma
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathString.Test", "MathString.Test\MathString.Test.csproj", "{7B36A0E0-0381-4671-80CF-91DA14DF20E0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CSharpHelper", "..\..\CSharpHelper\CSharpHelper\CSharpHelper.csproj", "{4603ED6E-4395-4866-BFDD-75363B3801AE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{55BB094F-90BB-4FA8-818C-92C5770552DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{55BB094F-90BB-4FA8-818C-92C5770552DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{55BB094F-90BB-4FA8-818C-92C5770552DE}.Debug|x86.ActiveCfg = Debug|Any CPU
{55BB094F-90BB-4FA8-818C-92C5770552DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{55BB094F-90BB-4FA8-818C-92C5770552DE}.Release|Any CPU.Build.0 = Release|Any CPU
{55BB094F-90BB-4FA8-818C-92C5770552DE}.Release|x86.ActiveCfg = Release|Any CPU
{7B36A0E0-0381-4671-80CF-91DA14DF20E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B36A0E0-0381-4671-80CF-91DA14DF20E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B36A0E0-0381-4671-80CF-91DA14DF20E0}.Debug|x86.ActiveCfg = Debug|Any CPU
{7B36A0E0-0381-4671-80CF-91DA14DF20E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B36A0E0-0381-4671-80CF-91DA14DF20E0}.Release|Any CPU.Build.0 = Release|Any CPU
{7B36A0E0-0381-4671-80CF-91DA14DF20E0}.Release|x86.ActiveCfg = Release|Any CPU
{4603ED6E-4395-4866-BFDD-75363B3801AE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4603ED6E-4395-4866-BFDD-75363B3801AE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4603ED6E-4395-4866-BFDD-75363B3801AE}.Debug|x86.ActiveCfg = Debug|x86
{4603ED6E-4395-4866-BFDD-75363B3801AE}.Debug|x86.Build.0 = Debug|x86
{4603ED6E-4395-4866-BFDD-75363B3801AE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4603ED6E-4395-4866-BFDD-75363B3801AE}.Release|Any CPU.Build.0 = Release|Any CPU
{4603ED6E-4395-4866-BFDD-75363B3801AE}.Release|x86.ActiveCfg = Release|x86
{4603ED6E-4395-4866-BFDD-75363B3801AE}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
162 changes: 149 additions & 13 deletions MathString/MathString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Linq;
using CSharpHelper;

namespace MathString
{
Expand Down Expand Up @@ -43,27 +44,99 @@ public string Operator
#endregion

}

public class Variable: IEqualityComparer<Variable>
{
#region Attributs

private readonly string _name;
private readonly float _value;

#endregion

#region Constructeur

public Variable(string name, float value)
{
_name = name;
_value = value;
}

#endregion

#region Proprietes

public string Name
{
get { return _name; }
}

public float Value
{
get { return _value; }
}

#endregion

/// <summary>
/// Détermine si les objets spécifiés sont égaux.
/// </summary>
/// <returns>
/// true si les objets spécifiés sont égaux ; sinon, false.
/// </returns>
/// <param name="x">Premier objet de type <paramref name="Variable"/> à comparer.</param>
/// <param name="y">Deuxième objet de type <paramref name="Variable"/> à comparer.</param>
public bool Equals(Variable x, Variable y)
{
return x.Name == y.Name;
}

/// <summary>
/// Retourne un code de hachage pour l'objet spécifié.
/// </summary>
/// <returns>
/// Code de hachage pour l'objet spécifié.
/// </returns>
/// <param name="obj"><see cref="T:Variable"/> pour lequel un code de hachage doit être retourné.</param>
/// <exception cref="T:System.ArgumentNullException">Le type de <paramref name="obj"/> est un type référence et <paramref name="obj"/> est null.</exception>
public int GetHashCode(Variable obj)
{
return (obj.Name.GetHashCode() + obj.Value.GetHashCode()).GetHashCode();
}
}
#endregion

#region Attributs
public const string NumberRegex = @"-?(?:\d+(?:[,\.]\d+)?)";
public const string TextRegex = @"[a-zA-Z_]+[a-zA-Z_\d]*";
public const string NumberRegex = @"-?(?:\d+(?:\.\d+)?)";
public const string DecimalRegex = @"-?(?:\d+(?:[,\.]\d+)?)";
public const string TextRegex = @"[a-zA-Z_]+[_\w]*";
public const string VariableRegex = @"\$("+TextRegex+");";
public const string FunctionRegex = @"\@("+TextRegex + @") ?\((" + NumberRegex + @")?(?:, ?(" + NumberRegex + @"))*\)";
public delegate string MathAction(string match);
private readonly Dictionary<Regex, MathStringTemplate> _mathFunc;
private readonly Dictionary<Variable, string> _variables;
private static readonly Dictionary<Variable, string> Variables;
#endregion

#region Constructeur
static MathString()
{
Variables = new Dictionary<Variable, string>();
}

public MathString()
{
_variables = new Dictionary<Variable, string>();

Func<string, MathAction> action = c =>
{
// ReSharper disable ConvertToLambdaExpression
return s =>
// ReSharper restore ConvertToLambdaExpression
{
string[] vals = Regex.Split(s, "(" + NumberRegex + ")(\\" + c + ")(" + NumberRegex + ")");
var val1 = float.Parse(vals[1].Trim()); //float.Parse(vals[0].Trim());
var val2 = float.Parse(vals[3].Trim());
var vals = Regex.Split(s, "(" + NumberRegex + ")(\\" + c + ")(" + NumberRegex + ")");
var val1 = float.Parse(vals[1].Replace('.', ',').Trim());
var val2 = float.Parse(vals[3].Replace('.', ',').Trim());
float result = 0f;
switch (c)
{
Expand All @@ -87,7 +160,7 @@ public MathString()
break;
}

return result.ToString();
return result.ToString("F");
};
};

Expand All @@ -108,24 +181,87 @@ public MathString()
for (int i = 0; i < sym.Length; i++)
foreach (string c in sym[i])
_mathFunc.Add(mathSymbols[c], new MathStringTemplate(c, i + 1, action(c)));

//foreach (string c in sym)
// _mathFunc.Add(mathSymbols[c], new MathStringTemplate(c, (c == "+" || c == "-" ? 2 : 1), action(c)));
}
#endregion

#region Methodes
public string Convert(string text)
public void AddVariable(Variable var)
{
if (_variables.ContainsKey(var))
_variables[var] = var.Value.ToString();
else
_variables.Add(var, var.Value.ToString());
}

public void AddVariables(IEnumerable<Variable> vars)
{
foreach (Variable variable in vars)
AddVariable(variable);
}

public static void AddGlobalVariable(Variable var)
{
if (Variables.ContainsKey(var))
Variables[var] = var.Value.ToString();
else
Variables.Add(var, var.Value.ToString());
}

public static void AddGlobalVariables(IEnumerable<Variable> vars)
{
foreach (Variable variable in vars)
AddGlobalVariable(variable);
}

public string Convert(string text, params Variable[] variables)
{
text = text.Replace(" ", "");
int max = _mathFunc.Values.Max(t => t.Weigth);
var pair = _mathFunc.First(kvp => kvp.Value.Operator == "number");
for (Match ma = pair.Key.Match(text); ma.Captures.Count != 0; ma = ma.NextMatch())
for (Match ma = pair.Key.Match(text); ma.Success; ma = ma.NextMatch())
text = text.Replace(ma.Value, pair.Value.Action(ma.Value));

text = FindVariables(text, variables);

return FindParenthesis(ref text, max, '(', ')') ? text : Calculate(text, max);
}

private string FindVariables(string text, ICollection<Variable> variables)
{
Regex varRegex = new Regex(VariableRegex);
IList<string> errors = new List<string>();
bool cont;

for (var ma = varRegex.Match(text); ma.Success; ma = (cont) ? ma.NextMatch() : varRegex.Match(text))
{
Variable variable = null;

if (variables.Count > 0)
variable = variables.FirstOrDefault(v => v.Name == ma.Groups[1].Value);

variable = variable ??
(_variables.Keys.FirstOrDefault(v => v.Name == ma.Groups[1].Value) ??
Variables.Keys.FirstOrDefault(v => v.Name == ma.Groups[1].Value));

if (variable != null)
{
text = text.Replace(ma.Value, variable.Value.ToString().Replace(',', '.'));
cont = false;
}
else
{
errors.Add(ma.Groups[1].Value);
cont = true;
}
}
if (errors.Count > 0)
throw new Exception(string.Format("Impossible de trouver {0} variable{1} : {2}",
errors.Count == 1 ? "la" : "les",
errors.Count > 1 ? "s" : "",
errors.Join(", ")));
return text;
}

private bool FindParenthesis(ref string text, int max, char open, char close)
{
while (text.Any(c => c == open || c == close))
Expand All @@ -138,7 +274,7 @@ private bool FindParenthesis(ref string text, int max, char open, char close)
{
po = text.Substring(po, pf - po).LastIndexOf(open) + po;
po++;
string subFormule = Calculate(text.Substring(po, pf - po), max); // Convert(text.Substring(po, pf - po));
string subFormule = Calculate(text.Substring(po, pf - po), max);
text = text.Substring(0, po - 1) + subFormule + text.Substring(pf + 1);
}
else
Expand All @@ -164,7 +300,7 @@ private string Calculate(string text, int max)
var regex = _mathFunc.First(kvp => kvp.Value.Operator == first.ToString());

Match ma = regex.Key.Match(text);
text = text.Replace(ma.Value, regex.Value.Action(ma.Value));
text = text.Replace(ma.Value, regex.Value.Action(ma.Value)).Replace(',', '.');
}

return text;
Expand Down
6 changes: 6 additions & 0 deletions MathString/MathString.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,12 @@
<Compile Include="MathString.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\CSharpHelper\CSharpHelper\CSharpHelper.csproj">
<Project>{4603ED6E-4395-4866-BFDD-75363B3801AE}</Project>
<Name>CSharpHelper</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down

0 comments on commit f079302

Please sign in to comment.