/// <summary> /// Overloaded + operator allows for more natural addition of integers to Fractions /// </summary> /// <param name="fractionAddend">RecipeFraction addend</param> /// <param name="integerAddend">Integer addend</param> /// <returns>Sum of addends</returns> public static RecipeFraction operator +(RecipeFraction fractionAddend, int integerAddend) { RecipeFraction fracCopy = fractionAddend.Copy(); fracCopy.Add(integerAddend); return(fracCopy); }
/// <summary> /// Overloaded / operator allows for more natural division of a RecipeFraction by an integer /// </summary> /// <param name="dividend">RecipeFraction dividend</param> /// <param name="divisor">Integer divisor</param> /// <returns>RecipeFraction quotient</returns> public static RecipeFraction operator /(RecipeFraction dividend, int divisor) { RecipeFraction fracCopy = dividend.Copy(); dividend.DivideBy(divisor); return(dividend); }
//Overloaded operators required in class definition because cannot use overloaded operators from parent class as returns type of parent class /// <summary> /// Overloaded + operator allows for more natural addition of a Fraction to a RecipeFraction /// </summary> /// <param name="addend1">RecipeFraction addend</param> /// <param name="addend2">Fraction addend</param> /// <returns>Sum of addends</returns> public static RecipeFraction operator +(RecipeFraction addend1, Fraction addend2) { RecipeFraction fracCopy = addend1.Copy(); fracCopy.Add(addend2); return(fracCopy); }
/// <summary> /// Overloaded * operator allows for more natural multiplication of a RecipeFraction by a Fraction /// </summary> /// <param name="factor1">RecipeFraction factor</param> /// <param name="factor2">Fraction factor</param> /// <returns>Product of factors</returns> public static RecipeFraction operator *(RecipeFraction factor1, Fraction factor2) { RecipeFraction fracCopy = factor1.Copy(); fracCopy.MultiplyBy(factor2); return(fracCopy); }
/// <summary> /// 2-arg constructor /// Even though Unit must be other, 2-arg constructor is provided to provide a constructor similar to that /// of other Measurements /// </summary> /// <param name="fraction"></param> /// <param name="unit"></param> public OtherMeasurement(RecipeFraction fraction, Unit unit) : base(fraction, unit) { if (unit != Unit.OTHER) { throw new UnsupportedUnitException("OtherMeasurement can only be constructed with Unit of type OTHER"); } }
/// <summary> /// Overloaded * operator allows for more natural multiplication of a RecipeFraction by an integer /// </summary> /// <param name="fractionFactor">RecipeFraction factor</param> /// <param name="integerFactor">Integer factor</param> /// <returns>Product of factors</returns> public static RecipeFraction operator *(RecipeFraction fractionFactor, int integerFactor) { RecipeFraction fracCopy = fractionFactor.Copy(); fractionFactor.MultiplyBy(integerFactor); return(fractionFactor); }
/// <summary> /// The AddTeaspoonsToCollection adds measurement of teaspoons to a Collection /// </summary> /// <param name="teaspoons">Number of teaspoons to add to Collection</param> /// <param name="measurements">Collection to which to add teaspoons Measurement</param> private static void AddTeaspoonsToCollection(ref RecipeFraction teaspoons, ICollection <Measurement> measurements) { if (teaspoons.CompareTo(0) > 0) { measurements.Add(new USCookingVolumeMeasurement(teaspoons, Unit.TEASPOON)); } }
/// <summary> /// Overloaded - operator allows for more natural subtraction of an integer from a RecipeFraction /// </summary> /// <param name="minuend">RecipeFraction minuend</param> /// <param name="subtrahend">Integer subtrahend</param> /// <returns>RecipeFraction difference</returns> public static RecipeFraction operator -(RecipeFraction minuend, int subtrahend) { RecipeFraction fracCopy = minuend.Copy(); fracCopy.Subtract(subtrahend); return(fracCopy); }
/// <summary> /// The GetCupsAsTeaspoons method returns the equivelant of /// a RecipeFraction of cups as a RecipeFraction of teaspoons /// </summary> /// <param name="fraction">RecipeFraction representing number of cups</param> /// <returns>RecipeFraction representing number of teaspoons</returns> private static RecipeFraction GetCupsAsTeaspoons(RecipeFraction fraction) { /*don't have to copy RecipeFraction because *= returns new RecipeFraction * and will therefore not be able to change fraction (it was not passed by value using ref/out)*/ fraction *= (RecipeConstants.TBSP_PER_CUP); return(GetTablespoonsAsTeaspoons(fraction)); }
public USCookingVolumeMeasurement(RecipeFraction fraction, Unit unit) : base(fraction, unit) { //must be a US volume unit if (!(unit == Unit.CUP || unit == Unit.TABLESPOON || unit == Unit.TEASPOON)) { throw new UnsupportedUnitException("Non-volume unit provided for USCookingVolumeMeasurement"); } }
/// <summary> /// The GetMeasurementsFromThirdCup method creates a Collection of the greatest possible Measurements /// the sum of which will equal the given number of teaspoons /// Starts with number of third cups and then quarter cups /// </summary> /// <param name="teaspoons">Fraction representing number of teaspoons</param> /// <returns>Collection of Measurements equal to number of teaspoons</returns> private static ICollection <Measurement> GetMeasurementsFromThirdCup(RecipeFraction teaspoons) { ICollection <Measurement> measurements = new List <Measurement>(); AddThirdCupsToCollection(ref teaspoons, measurements); //once have maximum third cups, use GetMeasurementsFromQuarterCups to get next greatest Measurements measurements = measurements.Concat(GetMeasurementsFromQuarterCup(teaspoons)).ToList(); return(measurements); }
/// <summary> /// The GetMixedFractionAsFraction method gets a mixed fraction (ie 1 1/2) as a Fraction /// </summary> /// <param name="match">Match containing mixed fraction</param> /// <returns>Improper fraction as RecipeFraction</returns> private static RecipeFraction GetMixedFractionAsFraction(Match match) { /* get the fraction portion of the mixed fraction as a fraction * Passes 1 as numeratorIndex because integer portion of mixed fraction will be the number at Captures' index 0 */ RecipeFraction fraction = GetFractionAsFraction(match, 1); //add the integer portion of the fraction (this happens second because integer addition is less costly) fraction += (System.Convert.ToInt32(match.Groups["integer"].Captures[0].Value)); return(fraction); }
/// <summary> /// The AddThirdCupsToCollection method adds as many third cup USVolumeMeasurements as can be formed from given number of teaspoons to a Collection /// The third cups are added as a single Measurement with a Fraction reflecting the number of third cups /// </summary> /// <param name="teaspoons">Fraction representing number of teaspoons</param> /// <param name="measurements">Measurements Collection to which to add third cups Measurement</param> private static void AddThirdCupsToCollection(ref RecipeFraction teaspoons, ICollection <Measurement> measurements) { int thirdCups = GetThirdCups(teaspoons); if (thirdCups > 0) { RecipeFraction cups = new RecipeFraction(thirdCups, 3); measurements.Add(new USCookingVolumeMeasurement(cups, Unit.CUP)); teaspoons -= (thirdCups * RecipeConstants.TSP_PER_THIRD_CUP); } }
/// <summary> /// The AddQuarterCupsToCollection method adds as many quarter cup USVolumeMeasurements as can be formed from given number of teaspoons to a Collection /// The quarter cups are added as a single measurement with a fraction reflecting the number of quarter cups /// </summary> /// <param name="teaspoons">Fraction representing number of teaspoons</param> /// <param name="measurements">Measurements Collection to which to add quarter cups Measurement</param> private static void AddQuarterCupsToCollection(ref RecipeFraction teaspoons, ICollection <Measurement> measurements) { int quarterCups = GetQuarterCups(teaspoons); if (quarterCups > 0) { RecipeFraction cups = new RecipeFraction(quarterCups, 4); measurements.Add(new USCookingVolumeMeasurement(cups, Unit.CUP)); teaspoons -= (quarterCups * RecipeConstants.TSP_PER_QUARTER_CUP); } }
/// <summary> /// The AddHalfTablespoonsToCollection method adds as many half tablespoon USVolumeMeasurements /// as can be formed from given number of teaspoons to a Collection /// The half tablespoons are added as a single measurement with a fraction reflecting the number of quarter cups /// </summary> /// <param name="teaspoons">Fraction representing number of teaspoons</param> /// <param name="measurements">Measurements Collection to which to add half tablespoons USCookingVolumeMeasurement</param> private static void AddHalfTablespoonsToCollection(ref RecipeFraction teaspoons, ICollection <Measurement> measurements) { int halfTbsp = GetHalfTablespoons(teaspoons); if (halfTbsp > 0) { RecipeFraction tbsp = new RecipeFraction(halfTbsp, 2); measurements.Add(new USCookingVolumeMeasurement(tbsp, Unit.TABLESPOON)); teaspoons -= (new Fraction((halfTbsp * RecipeConstants.TSP_PER_TBSP), 2)); } }
/// <summary> /// The GetFractionAsFraction method returns a RecipeFraction representing the fraction contained in a String /// </summary> /// <param name="match">Match containing fraction</param> /// <param name="numeratorIndex">Index at which Captures contains numerator of fraction if fraction is not represented as Unicode fraction</param> /// <returns>RecipeFraction</returns> private static RecipeFraction GetFractionAsFraction(Match match, int numeratorIndex = 0) { GroupCollection groups = match.Groups; RecipeFraction fraction; CaptureCollection integers = groups["integer"].Captures; if (groups["unicode_fraction"].Success) { fraction = GetFractionFromUnicode(groups["unicode_fraction"].Value); } else { int numerator = System.Convert.ToInt32(integers[numeratorIndex].Value); int denominator = System.Convert.ToInt32(integers[numeratorIndex + 1].Value); fraction = new RecipeFraction(numerator, denominator); } return(fraction); }
/// <summary> /// The GetMeasurementsFromQuarterCup method gets creates a Collection of the greatest possible Measurements /// the sum of which will equal the given number of teaspoons /// Uses quarter cup as greatest possible measurement /// </summary> /// <param name="teaspoons">Fraction representing number of teaspoons from which to get Measurements</param> /// <returns>Collection of Measurements equal to the teaspoon Fraction</returns> private static ICollection <Measurement> GetMeasurementsFromQuarterCup(RecipeFraction teaspoons) { ICollection <Measurement> measurements = new List <Measurement>(); if (teaspoons.EqualsValue(0)) { return(measurements); } AddQuarterCupsToCollection(ref teaspoons, measurements); if (teaspoons.EqualsValue(0)) { return(measurements); } AddHalfTablespoonsToCollection(ref teaspoons, measurements); if (teaspoons.EqualsValue(0)) { return(measurements); } AddTeaspoonsToCollection(ref teaspoons, measurements); return(measurements); }
private static RecipeFraction GetDecimalAsFraction(Match match) { RecipeFraction fraction = null; String decPartPattern = @"(?<=\.)\d+"; String wholePartPattern = @"\d*(?=\.)(?=\d*)"; String dec = match.Groups["decimal"].Value; int wholePart; Match wholeMatch = Regex.Match(dec, wholePartPattern); if (wholeMatch.Success) { Int32.TryParse(Regex.Match(dec, wholePartPattern).Value, out wholePart); } else { wholePart = 0; } Match decMatch = Regex.Match(dec, decPartPattern); if (decMatch.Success) { String decPartStr = decMatch.Value; int digits = decPartStr.Length; int decPart; Int32.TryParse(decPartStr, out decPart); double denominator = Math.Pow(10, digits); double numerator = wholePart * denominator; numerator += decPart; fraction = new RecipeFraction((int)numerator, (int)denominator); } //if there was no decimal number in the match, throw an Exception else { throw new ArgumentException("Argument does not contain decimal in supported format."); } return(fraction); }
/// <summary> /// Overloaded GetMeasurementReplacement method replaces the measurement /// in the given text, given a Unit /// </summary> /// <param name="amount">String containing measurement amount</param> /// <param name="unit">Unit of measurement</param> /// <returns></returns> private string GetMeasurementReplacement(String amount, Unit unit) { Measurement measurement; //gets the measurement as a fraction RecipeFraction fraction = GetFraction(amount); //perform the actual recipe conversion fraction *= multiplier; if (unit == Unit.OTHER) { measurement = new OtherMeasurement(fraction); } else { measurement = new USCookingVolumeMeasurement(fraction, unit); } //get user-friendly version of converted measurement ICollection <Measurement> measurements = measurement.UserFriendlyMeasurements(); String replacement = String.Join(" + ", measurements.Select(i => i.ToHTMLFormattedString())); //if there was a plus after the measurement amount, indicate that in the replacement text if (Regex.Match(amount, PLUS_PATTERN).Success) { //if more than one measurement, need to indicate that the 'plus' at the end refers to the combined group of measurements if (measurements.Count > 1) { replacement = "[" + replacement + "]<b>+</b>"; } else { replacement += "+"; //does not need to be bold if only one measurement } } return(replacement); }
/// <summary> /// The TeaspoonsToUserFriendlyMeasurements gets a collection of user friendly measurements /// from RecipeFraction of teaspoons /// </summary> /// <param name="teaspoons">RecipeFraction containing number of teaspoons in the recipe</param> /// <returns>Collection of user friendly measurements</returns> private static ICollection <Measurement> TeaspoonsToUserFriendlyMeasurements(RecipeFraction teaspoons) { //Get simplified measurements, using as many quarter cups as possible ICollection <Measurement> convertedMeasurements = GetMeasurementsFromQuarterCup(teaspoons.Copy()); int wholeTeaspoons = teaspoons.WholePart(); /** * If could get a third of a cup from converted recipe, get measurements * using third cups and then quarter cups (if applicable). * Then compare two Collections of Measurments to see if Collection with third cups is more user-friendly */ if (wholeTeaspoons >= RecipeConstants.TSP_PER_THIRD_CUP) { ICollection <Measurement> tCupMeasurements = GetMeasurementsFromThirdCup(teaspoons); //If same number of Measurements are returned, use Collection that starts with greater Measurement if (convertedMeasurements.Count == tCupMeasurements.Count) { /*can cast as USCookingVolumeMeasurement because was created in this class. * List is of type Measurement to be usable across multiple types of measurements. * Casting required to access Amount with its current access modifier and making public is undesirable*/ Fraction qCups = ((USCookingVolumeMeasurement)convertedMeasurements.ElementAt(0)).Amount; Fraction tCups = ((USCookingVolumeMeasurement)tCupMeasurements.ElementAt(0)).Amount; if (tCups.CompareTo(qCups) > 0) { convertedMeasurements = tCupMeasurements; } } //If the Collection with third cups is shorter than collection with quarter cups, use collection with third cups else if (tCupMeasurements.Count < convertedMeasurements.Count) { convertedMeasurements = tCupMeasurements; } } OptimizeMeasurements(convertedMeasurements); return(convertedMeasurements); }
/// <summary> /// The GetTablespoonsAsTeaspoons method the equivelant of /// a RecipeFraction of tablespoons as a RecipeFraction of teaspoons /// </summary> /// <param name="fraction">RecipeFraction representing number of tablespoons</param> /// <returns>RecipeFraction representing number of teaspoons</returns> private static RecipeFraction GetTablespoonsAsTeaspoons(RecipeFraction fraction) { return(fraction * (RecipeConstants.TSP_PER_TBSP)); }
/// <summary> /// The UserFriendlyMeasurements method returns a collection of measurements /// that is the user-friendly equivelant of the current USCookingVolumeMeasurement /// </summary> /// <returns></returns> public override ICollection <Measurement> UserFriendlyMeasurements() { RecipeFraction teaspoons = GetAsTeaspoons(); return(TeaspoonsToUserFriendlyMeasurements(teaspoons)); }
/// <summary> /// Constructor /// </summary> /// <param name="numerator">Numerator for fraction</param> /// <param name="denominator">Denominator for fraction</param> /// <param name="unit">Unit of measure</param> public Measurement(RecipeFraction fraction, Unit unit) { _amount = fraction; this._unitSize = unit; }
/// <summary> /// 1-arg constructor /// </summary> /// <param name="fraction">Fraction part of measurement</param> public OtherMeasurement(RecipeFraction fraction) : base(fraction, Unit.OTHER) { }