So I have the following loop:
for (int i = 1; i < numRows + 2; i++) //numRows was +4, now +2
{
Console.Clear();
Console.WriteLine("Number of rows: " + numRows);
Console.Write("Checking Row #: " + currRowNumber);
//We want to skip every row that is null and continue looping until we have more than 3 rows in a row that are null, then break
if (i > 1) {
i -= 1;
}
//Create Worksheet Range
Microsoft.Office.Interop.Excel.Range range = (Microsoft.Office.Interop.Excel.Range) excelWorkbookWorksheet.Cells[i, 2];
string cellValue = Convert.ToString(range.Value);
if (nullCounter == 3) //was 5
{
Console.WriteLine("\nNull row detected...breaking");
Console.WriteLine("Number of rows deleted: " + numRowsDeleted);
break;
}
if (cellValue != null) {
if (cellValue.Contains(searchText)) {
//Console.WriteLine("Deleting Row: " + Convert.ToString(cellValue));
((Range) excelWorkbookWorksheet.Rows[i]).Delete(XlDeleteShiftDirection.xlShiftUp);
numRowsDeleted++;
//Console.WriteLine("Number of rows deleted: " + numRowsDeleted);
nullCounter = 0;
i--;
currRowNumber++;
rowsPerSecond = i;
} else {
currRowNumber++;
nullCounter = 0;
}
} else {
nullCounter++;
//Console.WriteLine("NullCounter: " + nullCounter);
}
i++;
}
I want to calculate how many rows I'm looping through per second, then calculate from that number how long it will take to complete the entire loop, based on how many rows there are.
Check out setting up a Stopwatch at the beginning of the loop and check its Elapsed property at the end.
Its pretty trivial to get something simple up and running. Consider the following class:
public class TimePredictor
{
private readonly Stopwatch watch = new Stopwatch();
private double currentProgressRate;
public void Start() => watch.Restart();
public void Stop() => watch.Stop();
public double ElapsedTime => watch.ElapsedMilliseconds;
public void Update(long currentProgress)
{
currentProgressRate = watch.ElapsedMilliseconds / (double)currentProgress;
}
public double GetExpectedTotalTime(long total)
=> total * currentProgressRate;
public double GetExpectedTimeLeft(long total)
=> GetExpectedTotalTime(total) - watch.ElapsedMilliseconds;
}
And a trivial use case:
var repetitions = 200;
var predictor = new TimePredictor();
predictor.Start();
for (int i = 0; i < repetitions; i++)
{
Thread.Sleep((new Random()).Next(100, 250));
if (i % 5 == 0)
{
predictor.Update(i);
Console.WriteLine($"Iteration #{i}:");
Console.WriteLine($"\tExpected total time: {predictor.GetExpectedTotalTime(repetitions) / 1000.0:N1}");
Console.WriteLine($"\tExpected time left: {predictor.GetExpectedTimeLeft(repetitions) / 1000.0:N1}");
Console.WriteLine();
}
}
predictor.Stop();
Console.WriteLine($"Total time: {predictor.ElapsedTime / 1000.0:N1}");
You have 2 possible solutions:
Take the StopWatch and a Counter. Start the sw before you start with looping and increase the counter with ervery loop. At the end of a walktrough of the loop you can divide counter / sw.Elapsed
Use a Counter and a Timer with an interval of 1000ms. Increase the counter every time you go though the For-loop. With every tick you get the current Loops / Second.
EDIT: When you are finished with the for-loop stop the Timer and the StopWatch
Related
I tried changing my for loop with a parallel one but it's soo much slower instead of finishing the loop in a minute it finishes in 30 minutes. What the loop does is start with a number check if it's odd and if it's even. If it's odd it multiples by 3 and adds 1. If it's even it divides it by 2. Keep repeating that until the number reaches 4, and there is a loop around that repeats that a million times each time with a number higher by one. The last loop I mentioned is the loop I try to change to a parallel one. Here is the code for the normal for loop:
static void Main(string[] args)
{
BigInteger currenthighest =new BigInteger(Math.Pow(2,68));
BigInteger currentValue;
Console.WriteLine(currenthighest);
Console.ReadKey();
for (int i = 1; i > -1; i++)
{
for (int z = 0; z != 1000000; z++)
{
currentValue = currenthighest;
while (currentValue != 4)
{
if (currentValue % 2 == 0)
{
currentValue = currentValue / 2;
}
else
{
currentValue = (currentValue * 3) + 1;
}
}
currenthighest++;
}
Console.WriteLine(" {0} times done", i * 1000000);
}
}
And here is the code for the parallel one:
static void Main(string[] args)
{
BigInteger currenthighest =new BigInteger(Math.Pow(2,68));
BigInteger currentValue;
Console.WriteLine(currenthighest);
Console.ReadKey();
for (int i = 1; i > -1; i++)
{
Parallel.For(0, 1000000,z=>
{
currentValue = currenthighest;
while (currentValue != 4)
{
if (currentValue % 2 == 0)
{
currentValue = currentValue / 2;
}
else
{
currentValue = (currentValue * 3) + 1;
}
}
currenthighest++;
});
Console.WriteLine(" {0} times done", i * 1000000);
}
}
Can someone help me make it faster than a normal for loop or is using parallel in this situation stupid and I should just use normal for loop? If I will also appreciate any help to make normal for loop faster.
The reason for the performance deficit if as Theodor Zoulias points out probably due to it not being thread-safe. This can cause numbers to take arbitrary values and may cause totally different calculations to be performed.
To fix this you need to make each parallel loop independent. As far as I can tell this would be rather easy to do in your example since you only need to ensure that all modified values are local:
static void Main(string[] args)
{
BigInteger startvalue =new BigInteger(Math.Pow(2,68));
Console.WriteLine(startvalue );
Console.ReadKey();
for (int i = 1; i > -1; i++)
{
Parallel.For(0, 1000000,z=>
{
var currentValue = startvalue + z;
while (currentValue != 4)
{
if (currentValue % 2 == 0)
{
currentValue = currentValue / 2;
}
else
{
currentValue = (currentValue * 3) + 1;
}
}
});
Console.WriteLine(" {0} times done", i * 1000000);
}
}
Another possibility is that the work inside the parallel loop is on average quite small, causing the threading overhead to be significant. There is also the issue of work-balancing, Parallel.For will do work in 'chunks' to reduce this threading overhead, and try to adapt the size of these chunks. If the amount of work is highly variable this adaptation will probably result in inefficiencies.
static double calculateTotals(double a)
{
double transfee = a * .01;
double total = a + transfee;
return total;
}
static void Main(string[] args)
{
Console.WriteLine("How many dontations to process?");
int donations = Convert.ToInt16(Console.ReadLine());
int[] count = new int[] { donations + 1 };
int ct = 1;
int i = -1;
do
{
Console.WriteLine("Enter name: ");
string name = Console.ReadLine();
Console.WriteLine("Enter donation amount: ");
double amount = Convert.ToDouble(Console.ReadLine());
double transfee = amount * .01;
i++;
ct = count[i += 1];
Console.WriteLine(name + "\t" + amount + "\t" + transfee);
} while (i < donations);
Console.WriteLine("TOTALS:" + "\t" + calculateTotals(amount) + "\t" + transfee);
Console.ReadLine();
}
}
Hello. I am a beginner at coding, so I apologize if this is a poor attempt.
I am trying to make an app that records the amount donated by an individual, calculates a transaction fee, and outputs the results for each person. At the end, I am creating a final row of output that will state the total donations and the total transaction fees.
I am currently unsure how to properly implement the array into my loop, and am unsure if the loop is optimized in general.
Again, I am a beginner. I apologize for such code, but I'd love some clarification on these things.
Thank you!
First, your array declaration syntax is wrong. See this link.
So it should be int[] count = new int[donations+1];
Second, you need to declare and instantiate your amount and transfee variables outside of your loop.
double transfee = 0.0F;
double amount = 0.0F;
do
{
...
amount = Convert.ToDouble(Console.ReadLine());
transfee = amount * .01;
...
} while (i < donations);
This should be enough information to get you going again. Since you're learning, I don't think anyone would really unfold an answer for you that does the job you're trying to figure out :)
Your code :
int i = -1;
do
{
...
i++;
ct = count[i += 1];
...
} while (i < donations);
You are actually increase i two times, then get values from count[i] assign to ct variable
See this sample :
int[] count = new int[3];
count[0] = 0;
count[1] = 1;
count[2] = 2;
int i = -1;
do
{
i++;
int x = count[i += 1];
Console.WriteLine(x);
} while (i < 3);
It will cause IndexOutOfRangeException
Explain :
First Loop :
i++; // i increased 1, so i = 0
int x = count[i += 1]; // i increased 1, so i = 1, then get count[1] assign to x, x is 1
Second loop:
i++; // i increased 1, so i = 2
int x = count[i += 1]; // i increased 1, so i = 3, then get count[3] assign to x
count[3] cause IndexOutOfRangeException
Something like count[i += 1] will make your code more difficult to maintain, in my opinion, you should avoid it if possible, try to write it explicity as you can
I'm trying to write a code to find prime numbers within a given range. Unfortunately I'm running into some problems with too many repetitions that'll give me a stackoverflowexception after prime nr: 30000. I have tried using a 'foreach' and also not using a list, (doing each number as it comes) but nothing seems to handle the problem in hand.
How can I make this program run forever without causing a stackoverflow?
class Program
{
static void Main(string[] args)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
List<double> Primes = new List<double>();
const double Start = 0;
const double End = 100000;
double counter = 0;
int lastInt = 0;
for (int i = 0; i < End; i++)
Primes.Add(i);
for (int i =0;i< Primes.Count;i++)
{
lastInt = (int)Primes[i] - RoundOff((int)Primes[i]);
Primes[i] = (int)CheckForPrime(Primes[i], Math.Round(Primes[i] / 2));
if (Primes[i] != 0)
{
Console.Write(", {0}", Primes[i]);
counter++;
}
}
stopwatch.Stop();
Console.WriteLine("\n\nNumber of prime-numbers between {0} and {1} is: {2}, time it took to calc this: {3} (millisecounds).\n\n" +
" The End\n", Start, End, counter, stopwatch.ElapsedMilliseconds);
}
public static double CheckForPrime(double Prim, double Devider)
{
if (Prim / Devider == Math.Round(Prim / Devider))
return 0;
else if (Devider > 2)
return CheckForPrime(Prim, Devider - 1);
else
return Prim;
}
public static int RoundOff(int i)
{
return ((int)Math.Floor(i / 10.0)) * 10;
}
}
How to calculate the transfer rate speed in kilobyte per second, i used stopwatch but it doesnt work , because it gives me an error about div on zero ( count / 0)
public void sendFile(string filePath)
{
Stopwatch stopWatch = new Stopwatch();
FileInfo file = new FileInfo(filePath);
try
{
int fileSize = (int)file.Length;
Program.mainForm.MaxProgressBarHandler(fileSize);
byte[] fileDetial;
string detail = file.Name + "," + fileSize.ToString();
fileDetial = Encoding.ASCII.GetBytes(detail);
client.Send(fileDetial);
byte[] fileData = new byte[fileSize];
int count;
int sum = 0;
file.OpenRead().Read(fileData, 0, fileSize);
while (sum < fileSize)
{
stopWatch.Restart();
if (fileSize - sum < packetSize)
{
count = client.Send(fileData, sum, fileSize - sum, SocketFlags.None);
Program.mainForm.UpdateProgressBarHandler(count);
}
else
{
count = client.Send(fileData, sum, packetSize, SocketFlags.None);
Program.mainForm.UpdateProgressBarHandler(count);
}
stopWatch.Stop();
sum += count;
Program.mainForm.AppendLabel(((fileSize * 8) / stopWatch.ElapsedMilliseconds).ToString());
Console.WriteLine(sum + "of" + fileSize + "sent");
}
}
finally
{
Console.WriteLine("sent");
CloseClient();
}
}
Please help me =)
For first part of your question take a look a this Joel On Software Forum Thread. It is not specifically .Net related but is directly dealing with transferring a file using TCP.
As for second part, since I do not have your full code, so I am not able to see why your stopWatch.ElapsedMilliseconds is equal to zero. My guess is that there was no data to transfer. You could try doing something like this to avoid the divide by zero error.
if (stopWatch.ElapsedMilliseconds != 0)
Program.mainForm.AppendLabel(((fileSize * 8) / stopWatch.ElapsedMilliseconds).ToString());
Though I would probably have a 1 second timer and make sum a Class scoped variable and update your label every second i.e:
public partial class Form1 : Form
{
int sum = 0;
int seconds = 0;
...
private void timer1_Tick(object sender, EventArgs e)
{
seconds += 1;
Program.mainForm.AppendLabel(((sum * 8) / seconds).ToString());
}
and reset them when you finish your transfer.
....
finally
{
timer1.Stop();
sum = 0;
seconds = 0
Console.WriteLine("sent");
CloseClient();
}
I am creating a forecasting application that will run simulations for various "modes" that a production plant is able to run. The plant can run in one mode per day, so I am writing a function that will add up the different modes chosen each day that best maximize the plant’s output and best aligns with the sales forecast numbers provided. This data will be loaded into an array of mode objects that will then be used to calculate the forecast output of the plant.
I have created the functions to do this, however, I need to make them recursive so that I am able to handle any number (within reason) of modes and work days (which varies based on production needs). Listed below is my code using for loops to simulate what I want to do. Can someone point me in the right direction in order to create a recursive function to replace the need for multiple for loops?
Where the method GetNumbers4 would be when there were four modes, and GetNumbers5 would be 5 modes. Int start would be the number of work days.
private static void GetNumber4(int start)
{
int count = 0;
int count1 = 0;
for (int i = 0; 0 <= start; i++)
{
for (int j = 0; j <= i; j++)
{
for (int k = 0; k <= j; k++)
{
count++;
for (int l = 0; l <= i; l++)
{
count1 = l;
}
Console.WriteLine(start + " " + (count1 - j) + " " + (j - k) + " " + k);
count1 = 0;
}
}
start--;
}
Console.WriteLine(count);
}
private static void GetNumber5(int start)
{
int count = 0;
int count1 = 0;
for (int i = 0; 0 <= start; i++)
{
for (int j = 0; j <= i; j++)
{
for (int k = 0; k <= j; k++)
{
for (int l = 0; l <= k; l++)
{
count++;
for (int m = 0; m <= i; m++)
{
count1 = m;
}
Console.WriteLine(start + " " + (count1 - j) + " " + (j - k) + " " + (k - l) + " " + l);
count1 = 0;
}
}
}
start--;
}
Console.WriteLine(count);
}
EDITED:
I think that it would be more helpful if I gave an example of what I was trying to do. For example, if a plant could run in three modes "A", "B", "C" and there were three work days, then the code will return the following results.
3 0 0
2 1 0
2 0 0
1 2 0
1 1 1
1 0 2
0 3 0
0 2 1
0 1 2
0 0 3
The series of numbers represent the three modes A B C. I will load these results into a Modes object that has the corresponding production rates. Doing it this way allows me to shortcut creating a list of every possible combination; it instead gives me a frequency of occurrence.
Building on one of the solutions already offered, I would like to do something like this.
//Where Modes is a custom classs
private static Modes GetNumberRecur(int start, int numberOfModes)
{
if (start < 0)
{
return Modes;
}
//Do work here
GetNumberRecur(start - 1);
}
Thanks to everyone who have already provided input.
Calling GetNumber(5, x) should yield the same result as GetNumber5(x):
static void GetNumber(int num, int max) {
Console.WriteLine(GetNumber(num, max, ""));
}
static int GetNumber(int num, int max, string prefix) {
if (num < 2) {
Console.WriteLine(prefix + max);
return 1;
}
else {
int count = 0;
for (int i = max; i >= 0; i--)
count += GetNumber(num - 1, max - i, prefix + i + " ");
return count;
}
}
A recursive function just needs a terminating condition. In your case, that seems to be when start is less than 0:
private static void GetNumberRec(int start)
{
if(start < 0)
return;
// Do stuff
// Recurse
GetNumberRec(start-1);
}
I've refactored your example into this:
private static void GetNumber5(int start)
{
var count = 0;
for (var i = 0; i <= start; i++)
{
for (var j = 0; j <= i; j++)
{
for (var k = 0; k <= j; k++)
{
for (var l = 0; l <= k; l++)
{
count++;
Console.WriteLine(
(start - i) + " " +
(i - j) + " " +
(j - k) + " " +
(k - l) + " " +
l);
}
}
}
}
Console.WriteLine(count);
}
Please verify this is correct.
A recursive version should then look like this:
public static void GetNumber(int start, int depth)
{
var count = GetNumber(start, depth, new Stack<int>());
Console.WriteLine(count);
}
private static int GetNumber(int start, int depth, Stack<int> counters)
{
if (depth == 0)
{
Console.WriteLine(FormatCounters(counters));
return 1;
}
else
{
var count = 0;
for (int i = 0; i <= start; i++)
{
counters.Push(i);
count += GetNumber(i, depth - 1, counters);
counters.Pop();
}
return count;
}
}
FormatCounters is left as an exercise to the reader ;)
I previously offered a simple C# recursive function here.
The top-most function ends up having a copy of every permutation, so it should be easily adapted for your needs..
I realize that everyone's beaten me to the punch at this point, but here's a dumb Java algorithm (pretty close to C# syntactically that you can try out).
import java.util.ArrayList;
import java.util.List;
/**
* The operational complexity of this is pretty poor and I'm sure you'll be able to optimize
* it, but here's something to get you started at least.
*/
public class Recurse
{
/**
* Base method to set up your recursion and get it started
*
* #param start The total number that digits from all the days will sum up to
* #param days The number of days to split the "start" value across (e.g. 5 days equals
* 5 columns of output)
*/
private static void getNumber(int start,int days)
{
//start recursing
printOrderings(start,days,new ArrayList<Integer>(start));
}
/**
* So this is a pretty dumb recursion. I stole code from a string permutation algorithm that I wrote awhile back. So the
* basic idea to begin with was if you had the string "abc", you wanted to print out all the possible permutations of doing that
* ("abc","acb","bac","bca","cab","cba"). So you could view your problem in a similar fashion...if "start" is equal to "5" and
* days is equal to "4" then that means you're looking for all the possible permutations of (0,1,2,3,4,5) that fit into 4 columns. You have
* the extra restriction that when you find a permutation that works, the digits in the permutation must add up to "start" (so for instance
* [0,0,3,2] is cool, but [0,1,3,3] is not). You can begin to see why this is a dumb algorithm because it currently just considers all
* available permutations and keeps the ones that add up to "start". If you want to optimize it more, you could keep a running "sum" of
* the current contents of the list and either break your loop when it's greater than "start".
*
* Essentially the way you get all the permutations is to have the recursion choose a new digit at each level until you have a full
* string (or a value for each "day" in your case). It's just like nesting for loops, but the for loop actually only gets written
* once because the nesting is done by each subsequent call to the recursive function.
*
* #param start The total number that digits from all the days will sum up to
* #param days The number of days to split the "start" value across (e.g. 5 days equals
* 5 columns of output)
* #param chosen The current permutation at any point in time, may contain between 0 and "days" numbers.
*/
private static void printOrderings(int start,int days,List<Integer> chosen)
{
if(chosen.size() == days)
{
int sum = 0;
for(Integer i : chosen)
{
sum += i.intValue();
}
if(sum == start)
{
System.out.println(chosen.toString());
}
return;
}
else if(chosen.size() < days)
{
for(int i=0; i < start; i++)
{
if(chosen.size() >= days)
{
break;
}
List<Integer> newChosen = new ArrayList<Integer>(chosen);
newChosen.add(i);
printOrderings(start,days,newChosen);
}
}
}
public static void main(final String[] args)
{
//your equivalent of GetNumber4(5)
getNumber(5,4);
//your equivalent of GetNumber5(5)
getNumber(5,5);
}
}