Line separation / Line break in a listbox - c#

I want to display 2 sets of data on the one list box, for example, I would wont to display the 7 times table and the 8 times table on the same listbox. Here is how I get the first set of data displaying:
int awnser = 0;
int z;
z = int.Parse(textBox1.Text);
for (int i = 0; i < 11; i++)
{
awnser = z * i;
listBox6.Items.Add(z + " * " + i + " = " + awnser.ToString());
}
But how do I get a line break or separation so I can put the 8 times table just underneath?

How about this?
EDIT Insert it AFTER your loop
listBox6.Items.Add(z + " * " + i + " = " + awnser.ToString());
}
listBox6.Items.Add("--------------------");

In WPF this is easy to do using a custom template, but in WinForms I think you must do it by rendering the list items yourself.
Look at this example where they override the OnDrawItem method: http://www.syncfusion.com/FAQ/windowsforms/faq_c87c.aspx#q627q

Related

Visual Studio Pie Chart - Generate Percentages

I am generating pie charts by pulling data from SQL tables. The data is an accumulation of hours for different projects.
The charts are building fine but I would like the pie graph to display the respective percentage of each slice of the pie that is being used when the graphs are generated.
I am creating the charts in the method shown below.
// Fill Chart with usable data
for (int i = 0; i <= index - 1; i++)
{
Chart6.Series["Series1"].Points.AddXY(project[i], projTime[i]);
}
Chart6.Series[0]["PieLabelStyle"] = "Disabled";
I was hoping there would be a simple command I could pass in the code behind to create this but scouring the web has provided no usable results. The best I have found is this method but these are not options in Visual Studio Express 2013.
Prepare like this:
Series S = Chart6.Series["Series1"];
S.ChartType = SeriesChartType.Pie;
S.IsValueShownAsLabel = true;
S["PieLabelStyle"] = "Outside";
Create DataPoints like this if you know the total:
DataPoint p = new DataPoint(project[i], projTime[i]);
// check your data type for the calculation!
p.Label = p.YValues[0] + "h =\n" +
(100d * p.YValues[0] / total).ToString("00.00") + "%\n"; // my format
If you don't know the total, first set the points, then calculate the total and finally set the label:
for (int i = 0; i <= index - 1; i++)
{
S.Points.AddXY(project[i], projTime[i]);
}
// calculate the total:
double total = S.Points.Sum(dp => dp.YValues[0]);
// now we can set the percentages
foreach (DataPoint p in S.Points)
{
p.Label = p.YValues[0] + "h =\n" +
(100d * p.YValues[0] / total).ToString("00.00") + "%\n"; // my format
}
chart1.Titles.Add(S.Points.Count + " projects, total " +
total.ToString("###,##0") + " hours");
chart1.Titles[0].Font = new System.Drawing.Font("Arial", 14f);

Looping through multiple arrays to concatenate

I have 3 arrays. Two are arrays of strings and one is of date/time. I pulled all 3 from user input. Each array is always going to have the same exact amount of entries, so what I want to do is be able to loop through all 3 at once to make a string.
I was trying:
List<string> results = new List<string>();
// select
foreach (string line in array1)
{
foreach (string lines in array2)
{
foreach (DateTime date in datearray1)
{
results.Add("select * from table1 d, table2 c where d.specheader = c.specheader and c.true_false = true and d.number = " + lines.ToString() + " and d.date = '" + date.ToShortDateString() + "' and d.specnum like '%" + line.ToString() + "';");
}
}
}
results.ToArray();
foreach (string line in results)
{
MessageBox.Show(line);
}
The user types in information into 3 boxes and I'm just trying to concatenate sql statements based on the input. However when I tried doing it this way it looped through 6 times when I had only 2 entries. Is there a way to concatenate a string using all 3 arrays at the same time (so like entry 1 of array 1, entry 1 of array 2, entry 1 of array 3 - Then move on to creating the next string, entry 2 of array 1, entry 2 of array 2, entry 2 of array 3, etc.)
Any input would be appreciated. Thank you!
As the first commenter said (Yuck) don't use concatenation of strings into your SQL like that. You will want to setup an SQL Command and then pass in parameters.
That is however beside the point as you are asking about rolling together data from multiple arrays into 1 string.
Iterate through one of the arrays, If they all have the same count you will neatly get the data in one.
for(int i = 0; i < array1.Length; i++)
{
results.Add(string.format("Hello you! {0} , {1}, {2}", array1[i], array2[i], datearray[i])
}
This will get your desired result but your code is open to vulnerabilities as it stands. You need to change your approach.
Because your loops are nested, you're getting every value of array2 combined with every value in array1 (and similarly with datearray1. That's why you get too many results.
Your loops would work as intended like this (I've used similar local variables to avoid retyping the results.Add line, and to make clear how the code differs from yours):
for (int i = 0; i < array1.Length; i++)
{
string line = array1[i];
string lines = array2[i];
DateTime date = datearray1[i];
results.Add("select * from table1 d, table2 c where d.specheader = c.specheader and c.true_false = true and d.number = " + lines.ToString() + " and d.date = '" + date.ToShortDateString() + "' and d.specnum like '%" + line.ToString() + "';");
}
As a side-note: building a database query in this manner is inefficent and very insecure (try reading up on "Sql Injection" to understand why). You would see better results if you used a stored procedure instead.
if number of entries are going to be same for all you can simple do a for loop
for (int 1 = 0; i < datearray1.length; i++)
{
results.Add("select * from table1 d, table2 c
where d.specheader = c.specheader and c.true_false = true
and d.number = " + array2[i].ToString() + "
and d.date = '" + datearray1[i].ToShortDateString() + "'
and d.specnum like '%" + array1[i].ToString() + "';");
}

Converting C# to idiomatic R

Originally, I was using a short C# program I wrote to average some numbers. But now I want to do more extensive analysis so I converted my C# code to R. However, I really don't think that I am doing it the proper way in R or taking advantage of the language. I wrote the R in the exact same way I did the C#.
I have a CSV with two columns. The first column identifies the row's type (one of three values: C, E, or P) and the second column has a number. I want to average the numbers grouped on the type (C, E, or P).
My question is, what is the idiomatic way of doing this in R?
C# code:
string path = "data.csv";
string[] lines = File.ReadAllLines(path);
int cntC = 0; int cntE = 0; int cntP = 0; //counts
double totC = 0; double totE = 0; double totP = 0; //totals
foreach (string line in lines)
{
String[] cells = line.Split(',');
if (cells[1] == "NA") continue; //skip missing data
if (cells[0] == "C")
{
totC += Convert.ToDouble(cells[1]);
cntC++;
}
else if (cells[0] == "E")
{
totE += Convert.ToDouble(cells[1]);
cntE++;
}
else if (cells[0] == "P")
{
totP += Convert.ToDouble(cells[1]);
cntP++;
}
}
Console.WriteLine("C found " + cntC + " times with a total of " + totC + " and an average of " + totC / cntC);
Console.WriteLine("E found " + cntE + " times with a total of " + totE + " and an average of " + totE / cntE);
Console.WriteLine("P found " + cntP + " times with a total of " + totP + " and an average of " + totP / cntP);
R code:
dat = read.csv("data.csv", header = TRUE)
cntC = 0; cntE = 0; cntP = 0 # counts
totC = 0; totE = 0; totP = 0 # totals
for(i in 1:nrow(dat))
{
if(is.na(dat[i,2])) # missing data
next
if(dat[i,1] == "C"){
totC = totC + dat[i,2]
cntC = cntC + 1
}
if(dat[i,1] == "E"){
totE = totE + dat[i,2]
cntE = cntE + 1
}
if(dat[i,1] == "P"){
totP = totP + dat[i,2]
cntP = cntP + 1
}
}
sprintf("C found %d times with a total of %f and an average of %f", cntC, totC, (totC / cntC))
sprintf("E found %d times with a total of %f and an average of %f", cntE, totE, (totE / cntE))
sprintf("P found %d times with a total of %f and an average of %f", cntP, totP, (totP / cntP))
I would use the data.table package since it has group by functionality built in.
library(data.table)
dat <- data.table(dat)
dat[, mean(COL_NAME_TO_TAKE_MEAN_OF), by=COL_NAME_TO_GROUP_BY]
# no quotes for the column names
If you would like to take the mean (or perform other function) on multiple columns, still by group, use:
dat[, lapply(.SD, mean), by=COL_NAME_TO_GROUP_BY]
Alternatively, if you want to use Base R, you could use something like
by(dat, dat[, 1], lapply, mean)
# to convert the results to a data.frame, use
do.call(rbind, by(dat, dat[, 1], lapply, mean) )
I would do something like this :
dat = dat[complete.cases(dat),] ## The R way to remove missing data
dat[,2] <- as.numeric(dat[,2]) ## convert to numeric as you do in c#
by(dat[,2],dat[,1],mean) ## compute the mean by group
Of course to aggregate your result in a data.frame you can use the the classic , But I don't think is necessary here since it a list of 3 variables:
do.call(rbind,result)
EDIT1
Another option here is to use the elegant ave :
ave(dat[,2],dat[,1])
But the result is different here. In the sense you will get a vector of the same length as your original data.
EDIT2 To include more results you can elaborate your anonymous function:
by(dat[,2],dat[,1],function(x) c(min(x),max(x),mean(x),sd(x)))
Or returns data.frame more suitable to rbind call and with columns names:
by(dat[,2],dat[,1],function(x)
data.frame(min=min(x),max=max(x),mean=mean(x),sd=sd(x)))
Or use the elegant built-in function ( you can define your's also) summary:
by(dat[,2],dat[,1],summary)
One way:
library(plyr)
ddply(dat, .(columnOneName), summarize, Average = mean(columnTwoName))

Estimate loop time for progress bar

I'm currently using a loop in C# to generate files, but the program takes a few seconds to actually do this and I feel the program user would benefit from a progress bar that updates to tell them how far the loop is through so they can estimate when the loop is going to finish and all of their files are generated.
I was wondering if there was a way to calculate the time it's going to take a loop to complete or update a progress bar with the loop to show how much progress the loop has left.
Here's my loop.
String GeneratedLevelName;
int levelx = 0;
int levely = 0;
for (int i = 0; i < GmapLevelArea; i ++) {
if (levelx >= (GmapWidth - 1)) {
levelx = 0;
levely ++;
GeneratedLevelName = (GmapPrefix + "_" + levelx + "_" + levely + ".nw");
File.Copy(ApplicationDirectory + TemplateFileName, GmapDirectory + GeneratedLevelName);
GmapFile.AppendLine('"' + GeneratedLevelName + '"' + ",");
} else {
levelx ++;
GeneratedLevelName = (GmapPrefix + "_" + levelx + "_" + levely + ".nw");
File.Copy(ApplicationDirectory + TemplateFileName, GmapDirectory + GeneratedLevelName);
GmapFile.Append('"' + GeneratedLevelName + '"' + ",");
}
}
Any help is greatly appreciated.
Since it would be difficult to time the File.Copy, I think you should just base your progress bar on total files worked on.
So if you have a progress bar: pb
pb.Minimum = 0;
pb.Maximum = GMapLevelArea;
then set the value of the progress bar to you i value
pb.Value = i;
Now when I usually use progress bars like this, I usually don't update ever iteration. I usually update after a few iterations.
So to do that I usually check for the iteration count:
if(i % 10 == 0) //only true when i is a multiple of 10
pb.Value = i;
Then at the end of the loop, if it doesn't happen to be a multiple of your update, you can either set the progress bar to its maximum value or reset it to zero to let them no its done.
pb.Value = GMapLevelArea; or pb.Value = 0;
It depends on how consistent your files are generated (do they all take a second, or take some longer than others?) and if you know how many you are going to generate. In the easiest case, you can estimate the time by taking the number of files to generate. For example if you create 50 files, you can increment the progress bar by two percent after a file is generated.

AllFramesReady Repeating Loop

I am creating a program where you do rep of a stretch, so it adds one to amount of reps. I want to have a interval between each rep (not the current problem). I have this nested within the AllFramesReadyEventArgs. The problem is, since the SDK uses the AllFramesReadyEvent through out the whole program, so it is an infinite loop. How can I do each rep without it repeating when I don't want it to? Thanks in advance.
if (skeleton.TrackingState == SkeletonTrackingState.Tracked)
{
int whereIsX = (int)Canvas.GetLeft(ellipse1);
int whereToX = (int)Canvas.GetLeft(pspine);
whatToMultiplyX = whereToX / whereIsX;
int whereIsY = (int)Canvas.GetTop(ellipse1);
int whereToY = (int)Canvas.GetTop(pspine);
whatToMultiplyY = whereToY / whereIsY;
Canvas.SetTop(ellipse1, Canvas.GetTop(ellipse1) * whatToMultiplyY);
Canvas.SetLeft(ellipse1, Canvas.GetLeft(ellipse1) * whatToMultiplyX);
for (int i = 0; i < Doctor_ShoulderX.Count; i++)
{
Canvas.SetTop(doctorHand, Doctor_HandY[i] * whatToMultiplyY);
Canvas.SetTop(doctorElbow, Doctor_ElbowY[i] * whatToMultiplyY);
Canvas.SetTop(doctor_Shoulder, Doctor_ShoulderY[i] * whatToMultiplyY);
Canvas.SetLeft(doctorHand, Doctor_HandX[i] * whatToMultiplyX);
Canvas.SetLeft(doctorElbow, Doctor_ElbowX[i] * whatToMultiplyX);
Canvas.SetLeft(doctor_Shoulder, Doctor_ShoulderX[i] * whatToMultiplyX);
handX = Canvas.GetLeft(handright);
handY = Canvas.GetTop(handright);
elbowX = Canvas.GetLeft(elbowright);
elbowY = Canvas.GetTop(elbowright);
shoulderX = Canvas.GetLeft(shoulderright);
shoulderY = Canvas.GetTop(shoulderright);
shoulder_x.Text = "Shoulder X: " + shoulderX.ToString();
shoulder_y.Text = "Shoulder Y: " + shoulderY.ToString();
elbow_x.Text = "Elbow X: " + elbowX.ToString();
elbow_y.Text = "Elbow Y: " + elbowY.ToString();
hand_x.Text = "Hand X: " + handX.ToString();
hand_y.Text = "Hand Y: " + handY.ToString();
Patient_HandX.Add(handX);
Patient_HandY.Add(handY);
Patient_ElbowX.Add(elbowX);
Patient_ElbowY.Add(elbowY);
Patient_ShoulderX.Add(shoulderX);
Patient_ShoulderY.Add(shoulderY);
}
}
I'll use answer cause more writing than comment can handle :)
aleframesready action is invoked in every frame. so if here you have limit of 20 in loop
for (int i = 0; i < Doctor_ShoulderX.Count; i++)
it will be invoked from 0 to 20 every time. Imo you you should create a static boolean variable in the class. After the code go out from the loop set it to false (if on start it had true). Before you invoke the loop check if the variable is set to true. If yes invoke the loop, if no just continue

Categories