Please help with the code. How can you add numbers from 3,4,5 columns and transfer it to the "Total" column. At the same time, the "Total" column cannot be permanent, for example, listView1.Items [i] .SubItems [11] .Text - this solution is not appropriate, you need to possibly find the "Total" column itself because it is not permanent It can be like SubItems [ 9] 10.11, etc.
Code to write data to listView1
dataReader = await cmd1.ExecuteReaderAsync();
if (dataReader.FieldCount > 0)
{
for (int i = 0; i < dataReader.FieldCount; i++)
{
if (i == 0)
{
listView1.Columns.Add(dataReader.GetName(0), 0, HorizontalAlignment.Left);
}
else
{
listView1.Columns.Add(dataReader.GetName(i).ToString().Replace("_", " "), 80, HorizontalAlignment.Left);
}
}
ListViewItem lv = new ListViewItem();
//
while (await dataReader.ReadAsync())
{
lv = listView1.Items.Add(dataReader[dataReader.GetName(0)].ToString().Replace('_', ' '));
for (int h = 1; h < dataReader.FieldCount; h++)
{
lv.SubItems.Add(dataReader[dataReader.GetName(h)].ToString());
}
}
}
for (int i = 1; i < listView1.Columns.Count; i++)
listView1.Columns[i].Width = -2;
This code assumes there is a column named "Total" in listView1.
(int itt = 1; itt < listView1.Items.Count; itt++)
{
int Totall =
int.Parse(listView1.Items[itt].SubItems[2].Text) +
int.Parse(listView1.Items[itt].SubItems[3].Text) +
int.Parse(listView1.Items[itt].SubItems[4].Text);
//Сумма чисел добавить во всего
listView1.Items[itt].SubItems["Total"].Text = Totall.ToString();
}
int.Parse converts a string to an integer but keep in mind it will throw an exception if the string is not numerical. If you need error checking for that consider using int.TryParse.
Also note that SubItems are 0 indexed. Meaning 0 corresponds to the first visual column, 1 corresponds to the second.
Related
I need to display a Sheet so that the lines are aligned bottom and left. If there are no 10 characters in the word, the number of "+" characters is added so that the total of the line is 10 characters (see my output).
Why, when I print a List, I lose one row?
What's wrong with my piece of code? This matrix should be 10X10.
My output
List<string> filtredList = new List<string>() { "Jacuzzi", "Action", "Chinchilla", "Squeezebox", "Academic", "Abstract" };
int row = 10;
filtredList = Sorting(filtredList); //method is sorting by descending.
foreach (var item in filtredList) Console.WriteLine("Item: " + item + " length: " + item.Length);
Console.WriteLine("-------------------------------------");
//AFTER SORTING IN LIST:
//1)Squeezebox 2)Chinchilla 3)Academic 4)Abstract 5)Jacuzzi 6)Action
for (int i = 10; i > 0; i--)
{
try
{
if (filtredList[i].Length != 10)
{
Console.Write(filtredList[i]);
row = 10 - filtredList[i].Length;
Console.WriteLine(string.Concat(Enumerable.Repeat("+", row)));
}
else Console.WriteLine(filtredList[i]);
}
catch (SystemException)
{
row = 10;
Console.WriteLine(string.Concat(Enumerable.Repeat("+", row)));
}
}
Because your for loop is never gets to 0:
for (int i = 10; i > 0; i--)
i goes from 10 to 1 and that's why the first item of your list never prints.
Note:
Index of first item of an array or a list is 0
The better code would be:
for (int i = 9; i >= 0; i--)
Although you can use better alternatives for some of your code, but this will solve your problem.
EDIT:
You can use this approach (just change the for part to this) to not raise any exceptions (because its not normally a use case for try-catch)and also get faster results:
for (int i = 9; i >= 0; i--)
{
if (i < filtredList.Count)
{
if (filtredList[i].Length != 10)
{
Console.Write(filtredList[i]);
row = 10 - filtredList[i].Length;
Console.WriteLine(new string('+', row));
}
else Console.WriteLine(filtredList[i]);
}
else
{
row = 10;
Console.WriteLine(new string('+', row));
}
}
this is the program I'm trying to write:
Write a program that reads a text and line width from the console. The program should distribute the text so that it fits in a table with a specific line width. Each cell should contain only 1 character. It should then read a line with numbers, holding the columns that should be bombarded.
My code looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _04.Text_Bombardment
{
class Program
{
static void Main(string[] args)
{
var sentence = Console.ReadLine();
var bombing = int.Parse(Console.ReadLine());
var selected = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
Dictionary<int, bool> bombDict = new Dictionary<int, bool>();
var newSentence = sentence + new string(' ', bombing - sentence.Length % bombing); // whole row minus words left
for (int i = 0; i < selected.Length; i++)
{
bombDict.Add(selected[i], true);
}
var rows = newSentence.Length / bombing;
var cols = bombing;
var count = 0;
var arrSent = newSentence.ToCharArray();
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (bombDict.ContainsKey(j) && bombDict[j] == true && arrSent[count] != ' ')
{
arrSent[count] = ' ';
try
{
if (arrSent[count + bombing] == ' ')
{
bombDict[j] = false;
}
else
{
bombDict[j] = true;
}
}
catch (IndexOutOfRangeException)
{
continue;
}
}
count++;
}
}
var finalSent = string.Join("", arrSent).TrimEnd();
Console.WriteLine(finalSent);
}
}
}
And it breaks on this sentence:
Vazov received his elementary education in hisnative town of Sopoandat Plovdiv. The son of a conservative, well-to-do merchant.
20
1 6 17 2 5 0 15
Current Output:
ov eceived i e en ry educa i n hi ative to n of opo dat Plov iv. T e s of a co serva ive well-to- o mer ha t.
Intended Output:
ov eceived i e en ry educa i n hi ative to n of opo dat Plov iv. T e s of a co serva ive well-to- o mer han .
Soo it only doesn't work on the end.
Can someone help me?
Any suggestions?
Additional notes:
For example, we read the text "Well this problem is gonna be a ride." and line width 10. We distribute the text among 4 rows with 10 columns. We read the numbers "1 3 7 9" and drop bombs on those columns in the table.
The bombs destroy the character they fall on + all the neighbouring characters below it.
Note: Empty spaces below destroyed characters stop the bombs (see column 7).
Finally, we print the bombarded text on the console: "W l th s p o lem i o na be a r de."
Note: The empty cells in the table after the text should NOT be printed.
Your solution is very difficult to understand, keep it simple give names to the variables that you can understand easily.
I modified your code, hope it helps you:
static void Main()
{
string sentence = "Well this problem is gonna be a ride.";
int numberOfColumns = int.Parse("10");
List<int> bombs = "1 3 7 9".Split(' ').Select(int.Parse).ToList();
// we need to convert to decimal, otherwise C# will ignore decimal part.
//example: 127/20 = 6.35, so we need 7 rows. if we don't convert to decimal we have 6
// the Ceiling says, always round up. so even 6.1 will be rounded to 7
int numberOfRows = (int)Math.Ceiling(sentence.Length / Convert.ToDecimal(numberOfColumns));
char[,] array = new char[numberOfRows, numberOfColumns];
int sentencePointer = 0;
for (int rowIndex = 0; rowIndex < numberOfRows; rowIndex++)
{
for (int colIndex = 0; colIndex < numberOfColumns; colIndex++)
{
// if you want to print the grid with the full text, just comment the 3 lines below,
//and keep only "array[rowIndex, colIndex] = sentence[sentencePointer];"
if (bombs.Contains(colIndex))
{
if (sentence[sentencePointer] == ' ') // bomb is deactivated
{
bombs.Remove(colIndex);
array[rowIndex, colIndex] = sentence[sentencePointer];
}
else
array[rowIndex, colIndex] = '*'; // * represents a bomb
}
else
array[rowIndex, colIndex] = sentence[sentencePointer];
sentencePointer++; // move next character
if (sentencePointer >= sentence.Length)
break; // we reach the end of the sentence.
}
}
PrintGrid(array, numberOfRows, numberOfColumns);
// just give some space to print the final sentence
Console.WriteLine("");
Console.WriteLine("");
Console.WriteLine("");
for (int rowIndex = 0; rowIndex < numberOfRows; rowIndex++)
{
for (int colIndex = 0; colIndex < numberOfColumns; colIndex++)
{
Console.Write(array[rowIndex, colIndex]);
}
}
Console.ReadKey();
}
private static void PrintGrid(char[,] array, int numberOfRows, int numberOfColumns)
{
Console.WriteLine(new string('-', numberOfColumns * 2));
for (int rowIndex = 0; rowIndex < numberOfRows; rowIndex++)
{
Console.Write("|");
for (int colIndex = 0; colIndex < numberOfColumns; colIndex++)
{
Console.Write(array[rowIndex, colIndex]);
Console.Write("|");
}
Console.WriteLine("");
}
}
Somewhat more elegant solution.
private static IEnumerable<char> Bomb(IEnumerable<char> text, IEnumerable<int> indexes, int length)
{
var indexArray = new List<int>(indexes);
var used = new object[length];
return text.Select(
(c, index) =>
{
if (c != ' ' && indexArray.Contains(index % length))
{
used[index % length] = new object();
return '\0';
}
if (c == ' ' && used[index % length] != null)
{
indexArray.Remove(index % length);
}
return c;
});
}
I have a column named "HeaderText_Name" and in this column, I want to add a row that has the text "Row" under that column.
I attempted to write some pseudo-code for it
databaseGridView.Rows["HeaderText_Name"].Add("Row");
If I do
databaseGridView.Rows.Add("Row");
It adds it to the first column no matter what. I also can't do something like
databaseGridView.Rows.Add("","","Row");
Then it adds blanks to the first two columns and I also don't know how which index the column is. So I would be more helpful if it was by Name or text.
Here is the actual code I have so far..
for (int i = 0; i < completeInfoMatches.Count; i++) {
databaseGridView.Rows.Add();
databaseGridView.Rows[0].Cells[e.Node.Text].Value = completeInfoMatches[i].Groups[1].ToString();
}
Now, completeInfoMatches has more than 1 match because it's regex. How can I change the 0 to make it work?
UPDATE
int currentRowIndex = 0;
databaseGridView.Columns.Add(e.Node.Text.Replace(" ", string.Empty), e.Node.Text);
for (int i = 0; i < completeInfoMatches.Count; i++) {
databaseGridView.Rows.Add();
databaseGridView.Rows[currentRowIndex].Cells[e.Node.Text.Replace(" ", string.Empty)].Value = completeInfoMatches[i].Groups[1].ToString();
currentRowIndex = currentRowIndex + 1;
}
I'm getting a lot of extra blank rows because of Row.Add
Try something like this:
foreach(int i = 0; i < completeInfoMatches.Count; i++){
var index = databaseGridView.Rows.Add();
databaseGridView.Rows[index].Cells[e.Node.Text].Value = completeInfoMatches[i].Groups[1].ToString();
}
With the help of #Forlani ...
int currentRowIndex = 0;
int actualRowIndex = databaseGridView.Rows.Count;
for (int i = 0; i < completeInfoMatches.Count; i++) {
var index = 0;
if (actualRowIndex < completeInfoMatches.Count) {
index = databaseGridView.Rows.Add();
}
databaseGridView.Rows[currentRowIndex].Cells[e.Node.Text.Replace(" ", string.Empty)].Value = completeInfoMatches[i].Groups[1].ToString();
currentRowIndex = currentRowIndex + 1;
}
guys!
I need some help with my code.
So, the story is, I had a task to do a form application, where user could count entropy of discrete random variables. He types events and probabilities, and program calculates the entropy.
So I used DataGridView, a button and a TextBox. I've made everything, including restriction, such as "sum of all probabilities must be equal to 1".
But the thing I can't do is - the program itself must delete or ignore rows, which contain "0" or rows, which are empty (because formula of entropy contains log of a number, and log of 0 is an infinity, that's why program will output "NaN - not a number").
The main code is located in "button".
Here is a snippet of it:
for (int z = dataGridView1.Rows.Count - 1; z >= 0; z--)
{
if (dataGridView1[1, z].Value == null)
{
dataGridView1.Rows.Remove(dataGridView1.Rows[z]);
}
else if (dataGridView1[1, z].Value == "0")
{ dataGridView1.Rows.Remove(dataGridView1.Rows[z]);}
}
The only thing I get after this code, is an error saying, that it can't delete a new "transmitted" (don't know how to translate that to English) line.
This is the whole code, located in "button":
int counter = 1;
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
dataGridView1[0, i].Value = counter++;
}
double X = 0;
double A = 1;
for (int i = 0; i < dataGridView1.RowCount; i++)
{
X += Convert.ToDouble(dataGridView1[1, i].Value);
}
if (X < A && X > A)
{
MessageBox.Show("Cумма вероятностей меньше или больше 1, введите другие значения вероятностей", "АШИППКА", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
double H = 0;
for (int i = 0; i < dataGridView1.RowCount - 1; i++)
{
for (int z = dataGridView1.Rows.Count - 1; z >= 0; z--)
{
if (dataGridView1[1, z].Value == null)
{
dataGridView1.Rows.Remove(dataGridView1.Rows[z]);
}
else if (dataGridView1[1, z].Value == "0")
{ dataGridView1.Rows.Remove(dataGridView1.Rows[z]);}
}
double p = Convert.ToDouble(dataGridView1[1, i].Value);
H += p * Math.Log(p, 2.0);
}
textBox1.Text = Convert.ToString(-H);
}
Sorry for my bad english, it's not my native language, that's why there are a lot of mistakes. Please, ask, if you don't understand something.
Help me, please.
Elaborating on comment above.
If your DataGridView uses a DataTable or a BindingSource, e.g.
DataTable table = new DataTable();
table.Columns.Add(...);
DataGridView dgv = new DataGridView();
dgv.DataSource = table;
Anywhere your loops reference dataGridView1, replace that with table instead.
E.g.
for (int i = 0; i < table.Rows.Count; i++) {
//...
}
I tried this but this is not working.
I'm getting index out of bound exception.
for (int x = 0; x < newText.Count; x++)
{
for (int y = 0; y < WordsList.words.Length; y++)
{
if (!newText[x].Contains(WordsList.words[y]))
{
for (int n = 0; n < 3; n++)
newText.RemoveAt(x);
}
}
}
newText is a List
words is string[]
newText format is like this:
index 0 = this is a text hello all
index 1 = time&date (6/14/2014....)
index 2 = empty ""
index 3 = text hello world
index 4 = time&date (6/14/2014....)
index 5 = empty ""
And so on...
What i want to do is to loop over newText and if in index 0 there no any word(string) from words then remove index 0,1,2 next itertion check index 3 for any words if not exist one word or more remove indexs 3,4,5.
If in index 0 or 3 there is one word or more then do nothing dont remove anything.
In the end newText should be in the same format as before:
index 0 text line
index 1 date&time
index 2 empty ""
Just the new newText content will be with text lines that contain one ore more strings from words.
EDIT
This is what i tried now:
First this is how i build the List:
List<string> t = filterNumbers(text);
for (int i = 0; i < t.Count; i++)
{
if (!newText.Contains(t[i]))
{
newText.Add(t[i]);
newText.Add(dateTime[i]);
newText.Add("");
}
}
Removing numbers and leave only text and add it.
In the end in this case i have in newText 150 indexs. That's 50 indexs of text lines.
Then i tried this:
int lastindex = newText.Count - 1;
for (int i = newText.Count - 1; i >= 0; i--)
{
for (int x = 0; x < WordsList.words.Length; x++)
{
if (!newText[i].Contains(WordsList.words[x]))
{
if (i != lastindex)
{
newText.RemoveAt(i + 1);
}
newText.RemoveAt(i);
}
}
}
But i'm getting exception on the line:
if (!newText[i].Contains(WordsList.words[x]))
Index was out of range. Must be non-negative and less than the size of the collection
EDIT
If I understood correctly that you wanted to check whether a specific line contains some words and if not remove that and the two following lines, here is a possible solution:
// start at the bottom in the first line "that matters" and go down by 3
for (int x = newText.Count - 3; x >= 0; x-=3)
{
// check if the line contains any of the words specified
if (!WordsList.words.Any(w => newText[x].Contains(w)) || newText[x] == "")
{
// remove the checked line as well as the next two if not
l.RemoveRange(x, 3);
}
}
EDIT
Corrected the predicate to:
!WordsList.words.Any(w => newText[x].Contains(w));
from
!WordsList.words.Any(w => newText.Contains(w));
EDIT 2
Added the empty string as possibility
The problem was that if the line to test was empty, it would pass the test because it does not contain any word from WordsList.words. The test now includes the empty string as an option and removes it when encountered.
Looking at your logic:
(1) for (int i = newText.Count - 1; i >= 0; i--)
{
(2) for (int x = 0; x < WordsList.words.Length; x++)
{
if (...)
{
(3) newText.RemoveAt(i);
}
}
}
You can see that even if you removed lines in (3), you continue loop in (2) which can try again remove line in (2) for new indexes, which now become out of bounds
you need to add break after (3) to continue loop (1)
// For each 3-word-sets
for (int x = 0; x < newText.Count; x += 3)
{
// For each word in that 3-word-set
for (int k = x; k < 3; k++)
{
// Check each word
bool breakOut = false;
for (int y = 0; y < WordsList.words.Length; y++)
{
if (!newText[k].Contains(WordsList.words[y]))
{
newText.RemoveAt(x+2);
newText.RemoveAt(x+1);
newText.RemoveAt(x);
x -= 3;
breakOut = true;
break;
}
}
if (breakOut) { break; }
}
}
I just wanted to test and experiment with your original code. Haven't tested this. Just make sure the list contains 3×n items.
Ok, it seems your data structure is really bad. Anyway if you have to keep the structure as is I think this can work :
var newList = new List<string>();
for (int index = 0; index < newText.Count; index = index + 3)
{
if (WordsList.Any(t => newText[index].ToLower().Trim().Contains(t.ToLower().Trim())))
{
newList.AddRange(newText.Skip(index).Take(3));
}
}
newText = newList;