Calculating the previous quarter from the current Month in C# - c#

I'm sure there is a more consise way of achieving this result? However I created the following method to work out the previous quarter from the current month or DateTime passed in.
void Main()
{
var q = Helpers.PreviousQuarter();
q.Dump();
}
public class Helpers
{
public static int PreviousQuarter(DateTime? date = null)
{
var quarters = new Dictionary<int, int[]>();
quarters.Add(1, new[] { 1, 2, 3 });
quarters.Add(2, new[] { 4, 5, 6 });
quarters.Add(3, new[] { 7, 8, 9 });
quarters.Add(4, new[] { 10, 11, 12 });
foreach (var q in quarters)
{
if (q.Value.Any(m=> m == (date.HasValue ? date.Value.Month : DateTime.Now.AddMonths(-3).Month)))
return q.Key;
}
throw new ArgumentException("Could not calulate quarter.");
}
}

private int PreviousQuarter(DateTime date)
{
return (int)Math.Ceiling((double)date.AddMonths(-3).Month / (double)3);
}

This should do the trick
public static int PreviousQuarter(DateTime? date = null)
{
int month;
if (date.HasValue){
month = date.Value.Month;
} else {
month = DateTime.Now.AddMonths(-3).Month)
}
float quarter = month / 4;
return (int)Math.Ceiling(quarter +0.1);
}

Your current code is returning current quarter for a date you can modify your method like:
public static int CurrentQuarter(DateTime? date = null)
{
return (((date ?? DateTime.Now.AddMonths(-3)).Month - 1) / 3) + 1;
}
If you want to calculate previous quarter then you can use a single array instead of a dictionary like:
public static int PreviousQuarter(DateTime? date = null)
{
int[] previousQuarter = new[] {4, 4, 4, 1, 1, 1, 2, 2, 2, 3, 3, 3};
return previousQuarter[(date ?? DateTime.Now.AddMonths(-3)).Month];
}

Related

Load random scenes without repetition using c#

I want to load scenes randomly without repetition using c#. Any help would do.
Thanks.
int[] array = new int[] { 1, 2, 3, 4, 6, 8, 9, 10, 11, 12 };
List<int> list = new List<int>();
void Start()
{
list.AddRange(array);
}
int GetUniqueRandom(bool RemoveFromTheList)
{
if (list.Count == 0)
{
if (RemoveFromTheList)
{
list.AddRange(array);
}
else
{
return -1; // never repeat
}
}
int rand = Random.Range(0, 10);
int value = list[rand];
list.RemoveAt(rand); return value;
}
A nice clean way is to shuffle the array, then put all the elements in a stack. All you need to get a random element is to pop an item off the stack.
You will want to remove the list in the list of fields and replace with this;
Stack remainingScenes = new Stack();
Remove the content of the Start() method - you don't need it.
In your method to get a new number;
if (remainingScenes.Count == 0) {
int n = array.Length;
while (n > 1)
{
int k = rng.Next(n--);
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
foreach(var element in array) {
remainingScenes.Push(element);
}
}
return remainingScenes.Pop();
The shuffle method is from here.
Uhmmm, this looks very straightforward. Judging from your code, you only need a little modification to make it work..
List<int> list = new List<int>() { 1, 2, 3, 4, 6, 8, 9, 10, 11, 12 };
int GetUniqueRandom(bool RemoveFromTheList)
{
if (list.Count == 0)
{
return -1;//nothing in the list so return negative value
}
//generate random index from list
int randIndex = Random.Range(0, list.Count - 1);
int value = list[rand];
if(RemoveFromTheList)
{
list.RemoveAt(randIndex);
}
return value;
}
Try this:
int[] array = new int[] { 1, 2, 3, 4, 6, 8, 9, 10, 11, 12 };
Stack<int> stack = null;
Then initialize like this:
var rnd = new Random();
stack = new Stack<int>(array.OrderBy(x => rnd.Next()));
Now you just keep getting values from the stack until it is empty:
var value = stack.Pop();

A better way to fill a two-dimensional array with date and zodiac sign

I'm working on the following problem:
I want to fill a two-dimensional [365,2] Array. The first value is supposed to hold the date: starting with January 1st and ending with December the 31st. The second value is supposed to hold the corresponding Zodiac Sign to each date:
e.g. array[0, 0] holds 101 and array[0, 1] holds Aries and so on.
I've written a function:
public static void fill_array(string[,] year_zodiac, int days, string zodiac, string startdate, int starting_day)
{
//function to fill array with date and zodiac
int startdate_int = 0;
for (int i = starting_day; i <= days; i++)
{
year_zodiac[i, 0] = startdate;
year_zodiac[i, 1] = zodiac;
startdate_int = Int32.Parse(startdate);
startdate_int++;
startdate = startdate_int.ToString();
}
and call it like this:
fill_array(main_array, 18, "Aries", "101", 0);
This has to be done for every Zodiac sign. I circumvented the month break problem by simply calling fill_array twice (i.e. I call it once for the part of Aries in December and once for the part of aries in January).
This Solution works, but it seems incredibly crude to me.
Can anybody give me some pointers towards a more elegant solution?
Here is a class that does what you want, it has been tested. I did not fill out all signs on the first example, but when I re-factored it I did. I suggest you test this well as I only tested a few cases and might have missed some edge cases.
As has been pointed out to me by #ClickRick, I did start with his array/enum design, but found that lacking when using Linq and moved to a List. I also had to fix his data array so it would compile. I'm giving credit as is due.
public class Signs
{
static List<string> SignList = new List<string>() { "Aquarius", "Pisces", "Aries", "Taurus", "Not Found"};
static DateTime[] startDates = {
new DateTime(DateTime.Now.Year,1,21),
new DateTime(DateTime.Now.Year,2,20),
new DateTime(DateTime.Now.Year,3,21),
new DateTime(DateTime.Now.Year,4,21),
new DateTime(DateTime.Now.Year,12,31) };
static public string Sign(DateTime inDate)
{
return SignList.Zip(startDates, (s, d) => new { sign = s, date = d })
.Where(x => (inDate.Month*100)+inDate.Day <= (x.date.Month*100)+x.date.Day)
.Select(x => x.sign)
.First();
}
}
re-factored (this is clearer with the example above first)
public class Signs
{
static List<string> SignList = new List<string>() {
"Capricorn", "Aquarius", "Pisces", "Aries", "Taurus", "Gemini", "Cancer", "Leo", "Virgo", "Libra", "Scorpio", "Sagittarius", "Capricorn", "Not Found" };
static List<int> startDates = new List<int>() {
// month * 100 + day of month
120, 219, 320, 420, 521, 621, 722, 821, 923, 1023, 1122, 1222, 1232, 9999 // edge marker
};
static public string Sign(DateTime inDate)
{
return SignList[startDates.TakeWhile(d => (inDate.Month*100)+inDate.Day > d).Count()];
}
}
Why do you specifically want an array? Surely a more sophisticated data structure would help to encapsulate the functionality and help you to isolate your remaining code from knowing about the workings of it, and would also let you take account in the future of more subtle variations in the exact dates where they vary by year if you ever want to do that.
For example:
public class SO23182879
{
public enum StarSign
{
Aquarius, Pisces, Aries, Taurus, Gemini, Cancer,
Leo, Virgo, Libra, Scorpio, Sagittarius, Capricorn
};
static DateTime[] starSignStartDates = new DateTime[]
{
new DateTime(DateTime.Now.Year, 1, 20),
new DateTime(DateTime.Now.Year, 2, 19),
new DateTime(DateTime.Now.Year, 3, 21),
new DateTime(DateTime.Now.Year, 4, 20),
new DateTime(DateTime.Now.Year, 5, 21),
new DateTime(DateTime.Now.Year, 6, 21),
new DateTime(DateTime.Now.Year, 7, 23),
new DateTime(DateTime.Now.Year, 8, 23),
new DateTime(DateTime.Now.Year, 9, 23),
new DateTime(DateTime.Now.Year, 10, 23),
new DateTime(DateTime.Now.Year, 11, 22),
new DateTime(DateTime.Now.Year, 12, 22),
new DateTime(DateTime.Now.Year, 1, 20),
};
private class StarSignDateRange
{
public StarSign Sign { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
private List<StarSignDateRange> signStartDates = new List<StarSignDateRange>();
public SO23182879()
{
int date = 0;
foreach (StarSign sign in Enum.GetValues(typeof(StarSign)))
{
signStartDates.Add(new StarSignDateRange
{
Sign = sign,
StartDate = starSignStartDates[date],
EndDate = starSignStartDates[date + 1]
});
++date;
}
}
public StarSign Sign(DateTime date)
{
return signStartDates.First(
sd => date.Month == sd.StartDate.Month && date.Day >= sd.StartDate.Day ||
date.Month == sd.EndDate.Month && date.Day < sd.EndDate.Day
).Sign;
}
public void Test()
{
IList<DateTime> testDates = new List<DateTime>
{
new DateTime(2014,1,1),
new DateTime(2014,1,19),
new DateTime(2014,1,20),
new DateTime(2014,4,19),
new DateTime(2014,4,20),
new DateTime(2014,12,21),
new DateTime(2014,12,22),
new DateTime(2014,12,31),
};
foreach (DateTime d in testDates)
Console.WriteLine(string.Format("{0} is in {1}", d, Sign(d)));
}
}
As you'll see, I have completed the code which I had started earlier, and added a Test() method for you to see that the edge conditions work. I am grateful to Hogan for pointing out the "year zero" problem and other similar "gotchas" in my earlier sketch.

recursive appropriate route selection in list

I want to try to select routes from known points as seen below. But I cannot achieve to get appropriate route chain for example for point 2 to 8. According to this trial route1-route2 and route3 will be selected, but actually must be only route1 and route3, another example point 1 to point 11, my trial will give result all routes. How can I eliminate unnecessary routes.Is this possible with this trial or should I change my point of view?
static void Main(string[] args)
{
var route1 = new List<int> { 1, 2, 3, 4 };
var route2 = new List<int> { 1, 5, 6, 7 };
var route3 = new List<int> { 1, 8, 9, 10 };
var route4 = new List<int> { 10, 11, 12, 13 };
List<List<int>> routeList = new List<List<int>>();
routeList.Add(route1);
routeList.Add(route2);
routeList.Add(route3);
routeList.Add(route4);
int start = 3;
int end = 9;
var vistedRoutes = new List<List<int>>();
foreach(var route in routeList.FindAll(r => r.Contains(start)))
{
vistedRoutes.Add(route);
routeList.Remove(route);
FindPath(vistedRoutes, routeList, start, end);
if (vistedRoutes.Last().Contains(end))
{
break;
}
}
Console.WriteLine("done");
}
static void FindPath(List<List<int>> visitedRoutes, List<List<int>> remainingRoutes, int start, int end)
{
if (visitedRoutes.Last().Contains(end))
{
return;
}
for (int i = 0; i < remainingRoutes.Count; i++ )
{
var route = remainingRoutes[i];
foreach (var point in route)
{
if (visitedRoutes.Last().Contains(point))
{
visitedRoutes.Add(route);
var newRemainingRoutes = new List<List<int>>(remainingRoutes);
newRemainingRoutes.Remove(route);
FindPath(visitedRoutes, newRemainingRoutes, start, end);
if (visitedRoutes.Last().Contains(end))
{
return;
}
else
{
visitedRoutes.Remove(route);
}
}
}
}
}

sort list of struct of different types in net 2.0

Does anyone know how to sort a list of struct with different types (sample code below)?
We are currently using Net 2.0, so we cannot use Linq.
Thanks in advance!
public struct dataKeys
{
private long key1;
private long key2;
private string key3;
public long Key1;
{
get { return key1;}
set { key1 = value; }
}
public long Key2;
{
get { return key2;}
set { key2 = value; }
}
public string Key3;
{
get { return key3;}
set { key3 = value; }
}
}
. . .
List<dataKeys> dataKeyList = new List<dataKeys>();
// tried this but will only work for one
// dataKeyList.Sort((s1, s2) => s1.Key1.CompareTo(s2.Key1));
Something like:
FROM:
2, 2, C
1, 1, A
1, 3, A
3, 1, B
1, 2, B
2, 1, A
2, 3, A
1, 2, A
TO:
1, 1, A
1, 2, A
1, 2, B
1, 3, A
2, 1, A
2, 2, C
2, 3, A
3, 1, B
dataKeyList.Sort((s1, s2) => {
int result = s1.Key1.CompareTo(s2.Key1);
if(result == 0) {
result = s1.Key2.CompareTo(s2.Key2);
if(result == 0) {
result = s1.Key3.CompareTo(s2.Key3);
}
}
return result;
});
Or write a custom comparer (IComparer<dataKeys>), or have dataKeys implement IComparable<dataKeys>.
Yes, use .Sort with a custom comparison delegate:
http://msdn.microsoft.com/en-us/library/w56d4y5z%28v=VS.80%29.aspx

How to find out how many quarters there are beween one quarter and the other in c#

I've created a class called Kwartal (which translates into Quarter) for use in my program:
public sealed class Kwartal {
private DateTime _poczatekKwartalu;
private DateTime _koniecKwartalu;
private int _numerKwartalu;
private int _rok;
public Kwartal(int numer, DateTime dataod, DateTime datado) {
_numerKwartalu = numer;
_koniecKwartalu = datado;
_poczatekKwartalu = dataod;
_rok = dataod.Year;
}
public Kwartal() { }
public int Numer {
get { return _numerKwartalu; }
set { _numerKwartalu = value; }
}
public DateTime DataPoczatkowa {
get { return _poczatekKwartalu; }
set { _poczatekKwartalu = value; }
}
public DateTime DataKoncowa {
get { return _koniecKwartalu; }
set { _koniecKwartalu = value; }
}
public int Rok {
get { return _rok; }
set { _rok = value; }
}
}
It's basically definition for Quarter. Usually i define it like this:
Kwartal kwartal1 = new Kwartal(1, new DateTime(year, 1, 1), new DateTime(year, 3, 31));
Kwartal kwartal2 = new Kwartal(2, new DateTime(year, 4, 1), new DateTime(year, 6, 30));
Now i was wondering how I can do math on those. For example I've got Quarter1 in 2011 and i then have Quarter3 in 2012. I would like to find out how many quarters are there between Quarter1 and
Quarter3.
Like kwartal2 - kwartal1 = 5
Nowhere do you define the number of quarters in the year - without there being some property/constant set on the Kwartal object how can you know what the base value should be for your subtraction operation?
Once you've set that base value, the operation would be reasonably easy, you can create an absolute quarter count, e.g.
k.QuarterCount = (k1.year * kwartal.base) + k1.quarter
then you have an integer to substract from the other year.
From your answer, this is what I would do:
public static int zwrocRozniceMiedzyKwartalami(Kwartal kwartal1, Kwartal kwartal2) {
var quartersPerYear = 4;
var yearDifference = kwartal2.Rok - kwartal1.Rok;
var differenceQuarters = (yearDifference * quartersPerYear) + (kwartal2.Numer - kwartal1.Numer);
return differenceQuarters;
}
I think this would give you the following answers:
(Year1, Quarter1) - (Year2, Quarter2) = Difference
(2012, 2) - (2011, 1) = (2011 - 2012)*4 + (1 - 2) = -4 + (-1) = -5 => (2011, 1) is 5 quarters before (2012, 2)
(2014, 1) - (2018,3) = (2018 - 2014)*4 + (3 - 1) = 16 + 2 = 18 => (2018,3) is 18 months after (2014,1)
You can use the DateDiff class of the Time Period Library for .NET, respecting the calendar culture:
// ----------------------------------------------------------------------
public void DateDiffSample()
{
DateTime date1 = new DateTime( 2009, 11, 8, 7, 13, 59 );
Console.WriteLine( "Date1: {0}", date1 );
// > Date1: 08.11.2009 07:13:59
DateTime date2 = new DateTime( 2011, 3, 20, 19, 55, 28 );
Console.WriteLine( "Date2: {0}", date2 );
// > Date2: 20.03.2011 19:55:28
DateDiff dateDiff = new DateDiff( date1, date2 );
Console.WriteLine( "DateDiff.Quarters: {0}", dateDiff.Quarters );
// > DateDiff.Quarters: 5
} // DateDiffSample
First, you should define what the result of the calculation should be. Create a matrix/table with some data, and a lot of edge cases, and calculate by hand what the result should be.
Then, you could figure out an algorithm to use to calculate it. And basicly implement this algorithm. And test on your data you made up.
Oh, and then you start thinking about time-zones, daylight saving, etc. And you should read this blog entry from Jon Skeet.
I am not sure whether this is what you want to achieve
DateTime quarter1 = new DateTime(2010, 3, 31); //end date of Q1 as you capture DataKoncowa
DateTime quarter2 = new DateTime(2011, 3, 31);//end date of Q2 as you capture DataKoncowa
TimeSpan ts = quarter2 - quarter1; //kwartal2.DataKoncowa - kwartal1.DataKoncowa
int actualQuarters = ts.Days / (30 *3); //assuming quarter is 90 days
This returns 4 .. something like what you expect
If you convert the year / quarters to decimal, and do a little math, you can calculate the difference.
class DateTimeQuarter
{
public DateTimeQuarter(DateTime date)
{
Date = date;
Quarter = date.Month / 4 + 1;
}
public static int operator -(DateTimeQuarter lhs, DateTimeQuarter rhs)
{
double value = Convert.ToDouble(
(rhs.Date.Year - lhs.Date.Year)) + (rhs.Quarter / 10.0) - (rhs.Quarter / 10.0);
int result =
(Convert.ToInt32(value) * 4) + Convert.ToInt32(value - Math.Floor(value));
return result;
}
public DateTime Date { get; set; }
public int Quarter { get; set; }
}
static void Main(string[] args)
{
DateTimeQuarter q1 = new DateTimeQuarter(new DateTime(2006, 04, 20));
DateTimeQuarter q2 = new DateTimeQuarter(new DateTime(2007, 12, 25));
int quarters = q1 - q2;
}
This is how i ended up doing this. Seems to be working fine. If you've got a better way lemme know :-)
public static int zwrocRozniceMiedzyKwartalami(Kwartal kwartal1, Kwartal kwartal2) {
int quartersPerYear = 4;
int differenceQuarters;
int yearDifference = kwartal2.Rok - kwartal1.Rok;
if (yearDifference == 0) {
differenceQuarters = kwartal2.Numer - kwartal1.Numer;
return differenceQuarters;
} else if (yearDifference > 0) {
differenceQuarters = (yearDifference * quartersPerYear) + (kwartal2.Numer - kwartal1.Numer);
return differenceQuarters;
} else if (yearDifference < 0) {
return -1;
}
return -1;
}

Categories

Resources