I.m using c# language .I have a dictionary. the key is string of peoples emails. The value for each key is a list of objects. Those objects has 2 dateTime variables start and End.
What I'm trying to do is finding when is the time that all people I have are free. in addition to finding the times if some of them are available.
I managed to solve the first part which when all users are available. However, since I'm using a linear search the code is really slow.
so my questions are:
What is the better algorithm for doing this kind of comparison, keep in mind I'm comparing date ranges.
What is the best way to find if some of them are available at a specific time ??
This is the method responsible for intersection
private static FreeTime Intersection(FreeTime first, FreeTime second)
{
Console.WriteLine("inside intersection " + first.Start + " "+ first.End + " sescond " + second.Start + " " + second.End);
int result1 = DateTime.Compare(first.Start, second.End);
int result2 = DateTime.Compare(first.End, second.Start);
int result3 = DateTime.Compare(first.Start, second.Start);
int result4 = DateTime.Compare(first.End, second.End);
Boolean equal = (result3 == 0 && result4 == 0);
if (!(result1 >= 0) && !(result2 <= 0) && !equal)
{
Console.WriteLine(new DateTime(Math.Max(first.Start.Ticks, second.Start.Ticks)).TimeOfDay + "min max" + new DateTime(Math.Min(first.End.Ticks, second.End.Ticks)).TimeOfDay);
return new FreeTime(new DateTime(Math.Max(first.Start.Ticks, second.Start.Ticks)), new DateTime(Math.Min(first.End.Ticks, second.End.Ticks)));
}
else if (result3 == 0 && result4 == 0)
return (new FreeTime(first.Start, first.End));
else return null;
This part is for iterating through the lists
foreach (var t in allFree)
{
if (allFree != null)///&& list.Count > 1)
{
Console.WriteLine(t.Start + " " + t.End + " in all freeeee");
foreach (var s in allFree)
{
if (!((DateTime.Compare(t.Start.Date, s.Start.Date) == 0) && (DateTime.Compare(t.Start, s.Start) == 0) && (DateTime.Compare(t.End, s.End) == 0)) && (t.Start.Date == s.Start.Date))
{
Console.WriteLine("callling inteersection 2 ");
intersection = Intersection(t, s);
}
// else if ((list.Count == list2.Count) && ((DateTime.Compare(t.Start.Date, s.Start.Date) == 0) && (DateTime.Compare(t.Start, s.Start) == 0) && (DateTime.Compare(t.End, s.End) == 0)) && (t.Start.Date == s.Start.Date))
// intersection = new FreeTime(t.Start, t.End);
if (intersection != null)
{
finalFree.Add(intersection);
Console.WriteLine(intersection.Start + " " + intersection.End + " intersection result");
intersecFound = true;
}
}//end foreach
if (!intersecFound)
{
// allFree.Add(t);
intersecFound = false;
}
Related
This question already has answers here:
How to replace multiple if statements i to more compact code/class in C#?
(5 answers)
Closed last year.
I'm baby-new to c# and building a project on mental health with multiple objects - starting with loops. Is there more tactful way to approach this code?
I ran basic code input via following:
Console.WriteLine("How are you feeling (1-bad to 5 great)?");
var userInput = Console.ReadLine();
Console.WriteLine(" Mood: " + userInput);
if (! Int32.TryParse(userInput, out x))
{
Console.WriteLine("Invalid data input");
}
else if (x == 1)
{
Console.WriteLine(" very low.");
}
else if (x == 2)
{
Console.WriteLine(" low.");
}
else if (x == 3)
{
Console.WriteLine(" average.");
}
else if (x == 4)
{
Console.WriteLine(" good.");
}
else if (x == 5)
{
Console.WriteLine(" very good.");
}
try this, it is more compact code
var invalidData = false;
var x = 0;
var moods = new string[] { " very low.", " low.", " average.", " good.", " very good." };
do
{
Console.WriteLine("How are you feeling(1 - bad to 5 great)?");
var userInput = Console.ReadLine();
Console.WriteLine(" Mood: " + userInput);
if (!Int32.TryParse(userInput, out x) || x < 1 || x > 5)
{
Console.WriteLine("Invalid data input");
invalidData = true;
}
else invalidData = false;
}
while (invalidData);
Console.WriteLine(moods[x-1]);
I would like help.
There are some problems with the code.
I want to do only one inspection at a certain time every day.
In particular, the problem is the most serious in DateTime.Now.Hour == 11 part.
I am having difficulty checking certain times. I need to write code that can be checked only once at 11:00 in the whlie statement.
I created a license file and checked the date of the file.
public static CResult Dailytime(string date)
{
CResult result = new CResult();
if(result.nRet == 0)
{
while (true)
{
if (result.nRet == 1 || result.nRet == 2)
{
return result;
}
if (DateTime.Now.Hour == 11)
{
result = DailyCheckData(date);
if(result.nRet == 1 || result.nRet == 2)
{
return result;
}
}
System.Threading.Thread.Sleep(60 * 30 * 1000);
}
}
return result;
}
public static CResult DailyCheckData(string data)
{
CResult result = new CResult();
DateTime licenseDate = Convert.ToDateTime(data);
string dateNow = DateTime.Now.ToString("yyyy-MM-dd");
int compareDate = DateTime.Compare(Convert.ToDateTime(data), DateTime.Now);
if (licenseDate.ToString("yyyy-MM-dd") == dateNow)
{
result = ExpirationCertificate();
Console.WriteLine("Result = " + result.Result + " Msg = " + result.Msg + " nRet = " + result.nRet);
return result;
}
else
{
if (compareDate > 0)
{
result = TrueCertificate();
Console.WriteLine("Result = " + result.Result + " Msg = " + result.Msg + " nRet = " + result.nRet);
}
else if (compareDate <= 0)
{
result = ExpirationCertificate();
Console.WriteLine("Result = " + result.Result + " Msg = " + result.Msg + " nRet = " + result.nRet);
}
return result;
}
}
CResult class
nRet= 0 or 1 or 2
0 = fasle date
1 = false file
2 = true
Suggest or suggest ways to improve.
Can you try create a variable for DateTime.Now, after a line of code that value change.
DateTime licenseDate = Convert.ToDateTime(data);
string dateNow = DateTime.Now.ToString("yyyy-MM-dd");
int compareDate = DateTime.Compare(Convert.ToDateTime(data), DateTime.Now);
To
DateTime licenseDate = Convert.ToDateTime(data);
var now = DateTime.Now;
string dateNow = now.ToString("yyyy-MM-dd");
int compareDate = DateTime.Compare(licenseDate, now);
you shouldn't use Thread.Sleep() method for such a long duration. It is poor programming logic to make the thread sleep for such a long period.
What you can do to solve this is, is to make a Timer. There's an example attached in the link. A simple snippet to match your logic would be:
licenseStart = //setYours
lastCheck = DateTime.Now;
nextCheck = now.AddDays(1); // now.AddHours(1)
var timer = new Timer(o=>{/* Do work*/}, null, TimeSpan.Zero, nextCheck);
Hope it helps!
I asked about logic that can only loop once at 11 o'clock.
But I could not find the right answer and I found the answer.
I do not speak English well.
That's why others do not understand the intent of the question.
bool bOnce = true;
//bool s0nce = true;
while (true)
{
if (DateTime.Now.Hour == 11 && bOnce)
{
//run code
}
if (bOnce == true)
bOnce = false;
else
bOnce = true;
Thread.Sleep(10 * 60 * 1000);
}
Thanks for your feedback. I'm still getting an out of range exception. I'm debugging but can't understand why I'm getting the exception. If an int is higher than a certain other int it should work. Does it have anything to do with the length.Count?
UPDATED Code
do
{
Console.Write("Input the element that you want to exclude from the list: ");
result = int.TryParse(Console.ReadLine(), out delSelection);
tempInputDelInt = (int)(tempList[delSelection]);
tempInputDelStr = Convert.ToString(tempInputDelInt);
if (result == true && tempInputDelInt >= 0 && tempInputDelInt < tempList.Count)
{
tempList.RemoveAt(delSelection);
Console.WriteLine("\nYou've deleted the temperature " + tempInputDelStr + " from index " + delSelection);
success = false;
Console.ReadKey(true);
Console.Clear();
}
else if (result == true && tempInputDelInt >= tempList.Count || tempInputDelInt < 0)
{
Console.WriteLine("You've input a number that's outside the list. Input a digit between 0 and " + (tempList.Count - 1) + ".\n");
success = true;
Console.ReadKey(true);
}
else if (result == false)
{
Console.WriteLine("\nYou didn't input a digit, try again!\n");
success = true;
Console.ReadKey(true);
}
} while (success);
success = false;
I'm having some problems with the validation of the first else if statement. I want to catch the cases when a value outside of the array is input, but I don't manage to.
I've done a practically identical program with array.Length with success.
Is there any difference between array.List and list.Count? Is that's the problem?
Thanks in advance for your help!
do
{
Console.Write("Input the element that you want to exclude from the list: ");
result = int.TryParse(Console.ReadLine(), out delSelection);
tempInputDel = Convert.ToString(tempList[delSelection]);
if (result == true && delSelection >= 0 && delSelection < tempList.Count)
{
tempList.RemoveAt(delSelection);
Console.WriteLine("\nYou've deleted the temperature " + tempInputDel + " from index " + delSelection);
Console.ReadKey(true);
Console.Clear();
}
else if (result == true && delSelection >= tempList.Count || delSelection < 0)
{
Console.WriteLine("You've input a number that's outside the list. Input a digit between 0 and " + (tempList.Count - 1) + ".\n");
}
else if (result == false)
{
Console.WriteLine("\nYou didn't input a digit, try again!");
Console.ReadKey(true);
}
} while (result == false);
Change this
tempInputDelInt = (int)(tempList[delSelection]);
to this
tempInputDelInt = (int)delSelection;
Whatever number the user enters, you're using that as the index to determine which item to delete. So it's not a value you get from tempList.
I am assuming that your out-of-range exception happens here:
tempInputDel = Convert.ToString(tempList[delSelection]);
You cannot do this before checking, if delSelection is inside range of tempList. Move it inside first if block.
General advice:
You can use a debugger to go from statement to statement step-by-step to find the exact source code position where (e.g.) an exception is thrown.
I have a problem at the line String fromIndexString = topStiva.Substring(topStivaLength + 1, topStiva.Length); . I shows that topStiva.Length is out or range.
The code is as follows:
String actiuneRezultata(String topStiva, String cuvIntr) {
int index = -1;
String primulCharCuvIntr = cuvIntr.Substring(0, 1);
if (primulCharCuvIntr.Equals("+") == true)
primulCharCuvIntr = "\\" + primulCharCuvIntr;
else
if (primulCharCuvIntr.Equals("*") == true)
primulCharCuvIntr = "\\" + primulCharCuvIntr;
else
if (primulCharCuvIntr.Equals("*") == true)
primulCharCuvIntr = "\\" + primulCharCuvIntr;
else
if (primulCharCuvIntr.Equals("*") == true)
primulCharCuvIntr = "\\" + primulCharCuvIntr;
else
if (primulCharCuvIntr.Equals("*") == true)
primulCharCuvIntr = "\\" + primulCharCuvIntr;
for (int i = 0; i < ta.Length; i++) {
if (ta[i].CompareTo(primulCharCuvIntr) == 0) {
index = i;
break;
}
}
int topStivaLength = topStiva.Length - 1;
while (topStiva[topStivaLength] >= '0' && topStiva[topStivaLength] <= 9)
topStivaLength--;
String fromIndexString = topStiva.Substring(topStivaLength + 1, topStiva.Length);
int fromIndex = int.Parse(fromIndexString);
if (index < 0)
return "Nu face parte din gramatica!";
else
return tabela[fromIndex][index];
}
The value topStiva is gets it from the call actiuneRezultata(stivaAPD.Peek().ToString(), another_value)
I saw that in stivaAPD I am geeting after push some values. So why is it that is out of range? Pls help!
The second argument to String.Substring is the length of the desired substring. You seem to be calling it as if it were instead the (exclusive) end index of the substring. Try calling the following so that your length is equal to the distance to the end index of the string.
topStiva.Substring(topStivaLength+1, topStiva.Length - (topStivaLength+1));
If topStivaLength is -1, this (topStiva[topStivaLength] will cause an exception.
If topStivaLength is 0 and topStiva is an empty string, this (topStiva[topStivaLength] will cause an exception.
Next time indicate exactly on what line you are getting the exception.
I'm trying to show intervals of working hours/days it's should look like this:
(source: clip2net.com)
I have table where I'm storing day number, open time and closing time for each day
(source: clip2net.com)
Then I created query=>
var groups = from s in this.OpenTimes
orderby s.Day
group s by new { s.Till, s.Start } into gr
select new
{
Time = gr.Key.Start + "-" + gr.Key.Till,
Days = this.OpenTimes
.Where(o => o.Start == gr.Key.Start && o.Till == gr.Key.Till)
.OrderBy(d => d.Day).Select(d => d.Day).ToArray()
};
This query provides all grouped time intervals and days that included to this time-range
But I faced with problem - I created second half that representing this groups, but it's not working properly.
Maybe somebody could explain to me needed point of vision or this basic logic of showing opening times.
Thanks in advice...
Next approach works for me:
result screen
public string OpeningTimesString
{
get
{
if (!this.OpeningTimes.IsLoaded)
this.OpeningTimes.Load();
var groups = (from s in this.OpeningTimes
orderby s.Day, s.Start, s.Stop
group s by new { Stop = formatTime(s.Stop), Start = formatTime(s.Start), s.Day } into gr
select new
{
Time = gr.Key.Start + "-" + gr.Key.Stop,
Day = gr.Key.Day
}).ToList();
string result = "";
int tmp = 1;
for (int i = 0; i < groups.Count(); i++)
{
//One one = new One();
bool exit = false;
tmp = i;
while (exit == false)
{
if (i + 1 < groups.Count && groups[i].Time.Equals(groups[i + 1].Time))
{
i++;
}
else
{
if (tmp != i)
result += (NormalDayOfWeek)(groups[tmp].Day - 1) + "-" + (NormalDayOfWeek)(groups[i].Day - 1) + " : " + groups[i].Time + "<br />";
else
result += (NormalDayOfWeek)(groups[i].Day - 1) + " : " + groups[i].Time + "<br />";
exit = true;
}
}
}
if (result.IsNotNull())
return result;
else
return "[%Not yet defined]";
}
}