I have just started using 2D arrays, but can't seem to figure out how to get the average of each column. I am using a for loop to have the user enter the data( a students grade), then a for loop to display the information user entered. But after the information is displayed, I want to display the average of each column. What should I do get the average of each column?
This is the code I have so far
static void Main(string[] args)
{
double[,] grades = new double[2, 3];
double result;
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 3; j++)
{
Console.Write("Enter Grade " + (j + 1) + " For Group" + (i + 1) + ": ==>> ");
if (double.TryParse(Console.ReadLine(), out result)) grades[i, j] = result;
else
{
Console.WriteLine("*** INVALID GRADE ENTERED. PLEASE REENTER.");
}
}
}
for (int row = 0; row < 1; row++)
{
Console.WriteLine();
Console.Write(" Group " + (row + 1) + ": ");
Console.WriteLine(" Group " + (row + 2) + ": ");
Console.Write("=========== ===========");
for (int col = 0; col < 3; col++)
{
//String.Format("{0,-10} | {1,-10} | {2,5}",
//make pring for execise 2 Console.Write(string.Format("{0,-5}", grades[row, col]));
Console.WriteLine();
Console.Write(string.Format("{0,-9}", ""));
Console.Write(string.Format("{0,-20}",grades[0, col]));
Console.Write(grades[1,col]);
}
Console.WriteLine();
Console.WriteLine("=========== ===========");
}
Console.WriteLine("\n\npress any key to exit...");
Console.ReadKey();
//print it for exercise 1 myArr[o, column]; myArr[ , column]
}`
If you are looking for a special command that will do it for you, you're out of luck! You'll just have to write the code to do it, the same way you would normally average a series of numbers. Hint: The number of elements in the 'y' dimension of a 2D array is given by e.g. grades.GetLength(1).
To get Average per columns you need to traverse columns for a fixed row and add their values like this:
int columnTotal, average;
for (int row = 0; row < 2; row++)
{
columnTotal = 0;
for (int col = 0; col < 2; col++)
{
columnTotal += grades[row, col];
}
average = columnTotal/2;
Console.WriteLine("Average: {0}", average);
}
Related
{
int woodchuckSim = 0;
int numOfDays = 0;
bool validNumber = false;
bool validDays = false;
Random ran1 = new Random();
//display banner
//Ask user how many woodchucks to simulate
while(!validNumber)
{
Write("How many woodchucks would you like to simulate? (1 - 100) ");
int.TryParse(ReadLine(), out woodchuckSim);
if((woodchuckSim <= 0) || (woodchuckSim > 100))
{
WriteLine("\nPlease enter a correct amount of woodchucks to simulate: ");
}
else
{
validNumber = true;
}
}
//Ask user how many days to simulate
while(!validDays)
{
Write("\nHow many days would you like to simulate? (1 - 10) ");
int.TryParse(ReadLine(), out numOfDays);
if((numOfDays <= 0) || (numOfDays > 10))
{
WriteLine("Please enter a positive whole number between 1 and 10: ");
}
else
{
validDays = true;
}
}
//Using random class populate each cell between 1 and 50 that represents # of pieces of wood chucked by specific woodchuck on that specific day
int[,] sim = new int[woodchuckSim, numOfDays];
WriteLine($"{woodchuckSim} {numOfDays}");
for (int i = 0; i < sim.GetLength(0); i++)
{
for (int j = 0; j < sim.GetLength(1); j++)
{
sim[i, j] = ran1.Next(1, 50);
Write(sim[i, j] + "\t");
}
{
WriteLine(i.ToString());
}
}
WriteLine("Press any key to continue...");
ReadLine();
}
This is my code so far in my woodchuck simulation coding assignment but I need a columns and rows label on the side and top like the picture. I really don't have any idea how to do this, and I'm not sure if I'm missing a code or typed something wrong. Also at the end of the code it prints out the number of woodchucks simulated in a straight line like if the user typed in 15 it would print 0-14 in a straight line at the end which is not something I want, any help will be appreciated, thanks! (The second picture is what my code is printing)
There are a few steps to do this, but it's not too hard:
Write the column headers (include blank space at the beginning where the row headers go
Write the column underlines
For each row, write the row header first
Then for each column in the row, write the column data
After the column data is written, write a newline to start the next row
Here's a sample that produces a table similar to your output. Note that we use PadLeft to pad each column data with spaces so they're all the same width. I've also included Sum and Avg columns based on your comment below. Additionally, to clean up the main code, I added methods to write text in a different color and a method to get an integer from the user:
private static readonly Random Random = new Random();
private static void WriteColor(string text,
ConsoleColor foreColor = ConsoleColor.Gray,
ConsoleColor backColor = ConsoleColor.Black)
{
Console.ForegroundColor = foreColor;
Console.BackgroundColor = backColor;
Console.Write(text);
Console.ResetColor();
}
private static void WriteLineColor(string text,
ConsoleColor foreColor = ConsoleColor.Gray,
ConsoleColor backColor = ConsoleColor.Black)
{
WriteColor(text + Environment.NewLine, foreColor, backColor);
}
public static int GetIntFromUser(string prompt, Func<int, bool> validator = null)
{
var isValid = true;
int result;
do
{
if (!isValid)
{
WriteLineColor("Invalid input, please try again.", ConsoleColor.Red);
}
else isValid = false;
Console.Write(prompt);
} while (!int.TryParse(Console.ReadLine(), out result) ||
(validator != null && !validator.Invoke(result)));
return result;
}
public static void Main()
{
int columnWidth = 6;
ConsoleColor sumForeColor = ConsoleColor.DarkRed;
ConsoleColor sumBackColor = ConsoleColor.Gray;
ConsoleColor avgForeColor = ConsoleColor.White;
ConsoleColor avgBackColor = ConsoleColor.DarkGreen;
int numWoodchucks = GetIntFromUser(
"How many woodchucks would you like to simulate? (1 - 100) ... ",
x => x >= 1 && x <= 100);
int numDays = GetIntFromUser(
"How many days would you like to simulate? (1 - 10) .......... ",
x => x >= 1 && x <= 10);
int[,] data = new int[numWoodchucks, numDays];
// Write column headers, starting with a blank row header
Console.WriteLine();
Console.Write(new string(' ', columnWidth));
for (int col = 1; col <= data.GetLength(1); col++)
{
Console.Write($"{col}".PadLeft(columnWidth));
}
Console.Write(" ");
WriteColor("Sum".PadLeft(columnWidth - 1), sumForeColor, sumBackColor);
Console.Write(" ");
WriteLineColor("Avg".PadLeft(columnWidth - 1), avgForeColor, avgBackColor);
// Write column header underlines
Console.Write(new string(' ', columnWidth));
for (int col = 0; col < data.GetLength(1); col++)
{
Console.Write(" _____");
}
Console.Write(" ");
WriteColor("_____", sumForeColor, sumBackColor);
Console.Write(" ");
WriteLineColor("_____", avgForeColor, avgBackColor);
int total = 0;
for (int row = 0; row < data.GetLength(0); row++)
{
// Write row header
Console.Write($"{row + 1} |".PadLeft(columnWidth));
int rowSum = 0;
// Store and write row data
for (int col = 0; col < data.GetLength(1); col++)
{
data[row, col] = Random.Next(1, 50);
Console.Write($"{data[row, col]}".PadLeft(columnWidth));
rowSum += data[row, col];
}
// Write sum and average
Console.Write(" ");
WriteColor($"{rowSum}".PadLeft(columnWidth - 1),
sumForeColor, sumBackColor);
Console.Write(" ");
WriteLineColor($"{Math.Round((double) rowSum / data.GetLength(1), 1):F1}"
.PadLeft(columnWidth - 1), avgForeColor, avgBackColor);
total += rowSum;
}
// Write the sum of all the items
Console.Write(new string(' ', columnWidth + columnWidth * data.GetLength(1) + 1));
WriteColor("_____", sumForeColor, sumBackColor);
Console.Write(" ");
WriteLineColor("_____", avgForeColor, avgBackColor);
// Write the average of all the items
Console.Write(new string(' ', columnWidth + columnWidth * data.GetLength(1) + 1));
WriteColor($"{total}".PadLeft(columnWidth - 1), sumForeColor, sumBackColor);
Console.Write(" ");
WriteLineColor(
$"{Math.Round((double) total / (data.GetLength(0) * data.GetLength(1)), 1):F1}"
.PadLeft(columnWidth - 1), avgForeColor, avgBackColor);
Console.Write("\nPress any key to continue...");
Console.ReadKey();
}
Output
Not tested, but something like this:
Write("\t");
for (int i = 0; i < sim.GetLength(0); i++)
{
Write(i.ToString() + "\t");
}
WriteLine("\t");
for (int i = 0; i < sim.GetLength(0); i++)
{
Write("_____\t");
}
WriteLine();
for (int i = 0; i < sim.GetLength(0); i++)
{
{
WriteLine(i.ToString().PadLeft(3) + " |\t");
}
for (int j = 0; j < sim.GetLength(1); j++)
{
sim[i, j] = ran1.Next(1, 50);
Write(sim[i, j] + "\t");
}
}
Like I said, not tested, just typed right into the editor here, but that should get you close. Also, look at the string.PadLeft(int) function to get your numbers to be right-justified like the example.
I can transpose a square matrix, but now I'd like to transpose a non square matrix (in my code 3*2) with user input.
Other sources recommended me to create a new matrix first, which I have done. I manage to make the matrix, but when transposing, it stops from the 4th value.
I have looked at other topics but I can't find the error. Here is my code so far, can someone tell me where I went wrong?
Thanks!
//const
const int ROWS = 3;
const int COLS = 2;
//first matrix
int[,] matrix1 = new int[ROWS, COLS];
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
Console.Write("Enter num: ");
matrix1[i, j] = int.Parse(Console.ReadLine());
}
}
//output
Console.WriteLine("Eerste matrix: ");
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
Console.Write(matrix1[i, j] + " ");
}
Console.WriteLine(" ");
}
//transposed matrix
Console.WriteLine("Tweede matrix: ");
int[,] matrix2 = new int[COLS, ROWS];
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < COLS; j++)
{
matrix2[j, i] = matrix1[j, i];
Console.Write(matrix2[j, i] + " ");
}
Console.WriteLine(" ");
}
This is what I get when running the program:
//output
Enter num: 1
Enter num: 2
Enter num: 3
Enter num: 4
Enter num: 5
Enter num: 6
first matrix:
1 2
3 4
5 6
transposed matrix:
1 3
2 4
//--->> Only went up to 4th value?
So, at the beginning you load a matrix with fields : "i,j" => "row, column"
On the last step, you try accessing the matrix with a "j,i" => "column, row" order.
You're inverting the i,j indexes.-
Let me help you by just changing the variable names :
//const
const int ROWS = 3;
const int COLS = 2;
//first matrix
int[,] matrix1 = new int[ROWS, COLS];
for (int row = 0; row < ROWS; row++)
{
for (int column = 0; column < COLS; column ++)
{
Console.Write("Enter num: ");
matrix1[row, column] = int.Parse(Console.ReadLine());
}
}
//output
Console.WriteLine("Eerste matrix: ");
for (int row = 0; row < ROWS; row++)
{
for (int column = 0; column < COLS; column++)
{`enter code here`
Console.Write(matrix1[row, column] + " ");
}
Console.WriteLine(" ");
}
//transposed matrix
Console.WriteLine("Tweede matrix: ");
int[,] matrix2 = new int[COLS, ROWS];
for (int row = 0; row < ROWS; row++)
{
for (int column = 0; column < COLS; column++)
{
matrix2[column, row] = matrix1[row, column];
Console.Write(matrix2[column, row] + " ");
}
Console.WriteLine(" ");
}
// EDIT : actually noticed the sample didn't traspose it properly. fixed it.
Replace
matrix2[j, i] = matrix1[j, i];
with
matrix2[j, i] = matrix1[i, j];
This way a row number of matrix1 becomes a column number for matrix2 - i.e. the matrix gets transposed.
If you combine the other two answers, you will have a complete picture:
This line is wrong and will give you an IndexOutOfRangeException:
matrix2[j, i] = matrix1[j, i];
In order to transpose you need to flip the indices:
matrix2[j, i] = matrix1[i, j];
Another problem is that when you print the matrix, you switch rows and columns.
It's easier to just extract the code for each functionality into a separate method.
Also, using the names i and j can be confusing. They look alike and they don't convey their meaning. When working with matrices, I like to use r and c (or row and column)
void PrintMatrix(int[,] m)
{
int rows = m.GetLength(0);
int columns = m.GetLength(1);
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
Console.Write(m[r, c] + " ");
}
Console.WriteLine();
}
}
int[,] TransposeMatrix(int[,] m)
{
int rows = m.GetLength(0);
int columns = m.GetLength(1);
int[,] transposed = new int[columns, rows];
for (int r = 0; r < rows; r++) {
for (int c = 0; c < columns; c++) {
transposed[c, r] = m[r, c];
}
}
return transposed;
}
Then the last part of your code becomes simply:
PrintMatrix(matrix1);
Console.WriteLine();
int[,] matrix2 = TransposeMatrix(matrix1);
PrintMatrix(matrix2);
I have an array and i want to extract specific column from it, let's say the 3rd column only.
Example:
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
What is want is to extract 3rd column and display only:
3
3
3
3
This is my code where i am able to create a dynamic array specified by the user:
int r;
int c;
Console.Write("Enter number of rows: ");
r = (int)Convert.ToInt32(Console.ReadLine());
Console.Write("Enter number of columns: ");
c = (int)Convert.ToInt32(Console.ReadLine());
int[,] matrix = new int[r, c];
/*Insert Values into Main Matrix
--------------------------------------------------------------------------------*/
for (int row = 0; row < r; row++)
{
for (int col = 0; col < c; col++)
{
Console.Write("Enter value for matrix[{0},{1}] = ",row, col);
matrix[row, col] = (int)Convert.ToInt32(Console.ReadLine());
}
}
/*Print and show initial Matrix
--------------------------------------------------------------------------------*/
Console.WriteLine("Your matrix is,");
for (int row = 0; row < r; row++)
{
for (int col = 0; col < c; col++)
{
Console.Write(matrix[row, col] + " ");
}
Console.WriteLine();
}
/*Fixing first 2 columns
--------------------------------------------------------------------------------*/
int startingMatrixCols = 2;
Console.WriteLine("Fixed first 2 columns:");
for (int row = 0; row < r; row++)
{
for (int col = 0; col < startingMatrixCols; col++)
{
Console.Write(matrix[row, col] + " ");
}
Console.WriteLine();
}
var column = 2; // your expected column
//if it needs to be dynamic, you can read it from user entry
// Console.Write("Enter expected column: ");
// column = int.Parse(Console.ReadLine()); //enhance with error checks
for (int row = 0; row < r; row++)
{
Console.Write(matrix[row, column] + " ");
}
Console.Write("Enter the column number to display ");
int displayColNo = (int)Convert.ToInt32(Console.ReadLine());
/*If displayColNo=3 it displays only 3rd column numbers*/
for (int row = 0; row < r; row++)
{
Console.Write(matrix[row, displayColNo]);
Console.WriteLine();
}
Hi guys i am trying to create a retrieve method to retrieve a sum total of my 2d array values i have built the array to fill from user input but not sure how to total all array values as i am still learning.
public int[,] ToysMade = new int[4, 5];
public String[] days = new String[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday" };
public void UserInput()
{
String value;
int numCount;
//retrieveing length of ToysMade array dimensions if less than 0 repeat untill last dimension filled
for (int i = 0; i < ToysMade.GetLength(0); i++)
{
for (int ii = 0; ii < ToysMade.GetLength(1); ii++)
{
//taking user input for array dimension 0 "first dimension" then increment it by 1 after input ready for next dimension "i + 1"
value = Microsoft.VisualBasic.Interaction.InputBox("Enter Value For " + days[ii] + " of week " + (i + 1).ToString() + " Enter Value");
try
{
//making sure for only int past through
while (!(int.TryParse(value, out numCount)))
{
MessageBox.Show("Not a valid number, please try again.");
value = Microsoft.VisualBasic.Interaction.InputBox("Enter Value for " + days[i] + " of week " + (i + 1).ToString() + " Enter Value");
}
// taking values enterd from user and set next dimension for next input by incrementing it
ToysMade[i, ii] = numCount;
}
catch (Exception e)
{
MessageBox.Show("Value enterd is not in a valid format");
}
}
}
}
I suggest put either simple foreach loop
int total = 0;
foreach (var item in ToysMade)
total += item;
or nested loops which are typical for 2d arrays
int total = 0;
for (int i = 0; i < ToysMade.GetLength(0); i++)
for (int j = 0; j < ToysMade.GetLength(1); j++)
total += ToysMade[i, j];
You can use Linq by creating an IEnumerable<int>from ToysMade;
var total = ToysMade.Cast<int>().Sum();
Thanks guys awesome works thanks heaps again
public void Sum()
{
int total = 0;
for(int i = 0;i < ToysMade.GetLength(0); i++)
{
for(int j = 0;j < ToysMade.GetLength(1); j++)
{
total += ToysMade[i, j];
}
}
txtOutput.Text += "\r\nThe sum of products is: " + total.ToString();
}
So I'm building a multiplication table for my C# class. I've got the code for the table complete, and it works as advertised. The issue is that I need a dynamically changing top border, because the table is as wide as the number the user enters for the width digit, at 5 character spacing. Any thoughts?
static void Main(string[] args)
{
int width, height;
//int tableWidth;
Console.Write("How wide do we want the multiplication table? ");
width = Convert.ToInt32(Console.ReadLine());
Console.Write("How high do we want the multiplication table? ");
height = Convert.ToInt32(Console.ReadLine());
Console.Write(" x|");
for (int x = 1; x <= width; x++)
Console.Write("{0, 5}", x);
Console.WriteLine();
for (int row = 1; row <= height; row++)
{
Console.Write("{0, 5}|", row);
for (int column = 1; column <= height; ++column)
{
Console.Write("{0, 5}", row * column);
}
Console.WriteLine();
}
Console.ReadLine();
}
I assume tableWidth needs to be calculated, and then a Console.Write("_") equal to the width of the total table. Thanks in advance for your help :)
You need to use another loop, like this:
Console.Write("How wide do we want the multiplication table? ");
int width = Convert.ToInt32(Console.ReadLine());
Console.Write("How high do we want the multiplication table? ");
int height = Convert.ToInt32(Console.ReadLine());
Console.Write(" ");
for (int i = 0; i < width; i++)
Console.Write("_____");
Console.WriteLine("__");
Console.Write(" x|");
for (int x = 1; x <= width; x++)
Console.Write("{0, 5}", x);
Console.WriteLine();
for (int row = 1; row <= height; row++)
{
Console.Write("{0, 5}|", row);
for (int column = 1; column <= height; ++column)
{
Console.Write("{0, 5}", row * column);
}
Console.WriteLine();
}
Console.ReadLine();
You basically want to multiply the width by the padding you have given (5). Something like this will work. Keep in mind that I think you should break some of the spacing out into variables because you are re-using constant values like 5 in many places. Also the spacing before the x and the pipe should probably be a string variable, otherwise it is hard to see how many spaces go into each one. Here is my solution keeping the code in the same format you have so far:
Console.Write(" x|");
for (int x = 1; x <= width; x++)
Console.Write("{0, 5}", x);
Console.WriteLine();
Console.Write(" |");
for (int x = 1; x <= (width * 5); x++)
Console.Write("-");
Console.WriteLine();
Making the whole method:
static void Main(string[] args)
{
int width, height;
//int tableWidth;
Console.Write("How wide do we want the multiplication table? ");
width = Convert.ToInt32(Console.ReadLine());
Console.Write("How high do we want the multiplication table? ");
height = Convert.ToInt32(Console.ReadLine());
Console.Write(" x|");
for (int x = 1; x <= width; x++)
Console.Write("{0, 5}", x);
Console.WriteLine();
Console.Write(" |");
for (int x = 1; x <= (width * 5); x++)
Console.Write("-");
Console.WriteLine();
for (int row = 1; row <= height; row++)
{
Console.Write("{0, 5}|", row);
for (int column = 1; column <= height; ++column)
{
Console.Write("{0, 5}", row * column);
}
Console.WriteLine();
}
Console.ReadLine();
}
Here is your code with improved naming and top line drawing (btw you have incorrect rows displaying - you are iterating over rows instead of columns in second loop):
const int columnWidth = 5;
string cellFormat = "{0, " + columnWidth + "}";
Console.Write("How wide do we want the multiplication table? ");
int columnsCount = Convert.ToInt32(Console.ReadLine());
Console.Write("How high do we want the multiplication table? ");
int rowsCount = Convert.ToInt32(Console.ReadLine());
string title = String.Format(cellFormat + "|", "x");
Console.Write(title);
for (int i = 1; i <= columnsCount; i++)
Console.Write(cellFormat, i);
Console.WriteLine();
int tableWidth = columnWidth * columnsCount + title.Length;
Console.WriteLine(new String('-', tableWidth));
for (int row = 1; row <= rowsCount; row++)
{
Console.Write(cellFormat + "|", row);
for (int column = 1; column <= columnsCount; column++)
Console.Write(cellFormat, row * column);
Console.WriteLine();
}
Next refactoring step is extracting classes and methods:
Console.Write("How wide do we want the multiplication table? ");
int columnsCount = Convert.ToInt32(Console.ReadLine());
Console.Write("How high do we want the multiplication table? ");
int rowsCount = Convert.ToInt32(Console.ReadLine());
MultiplicationTable table = new MultiplicationTable(columnsCount, rowsCount);
table.Draw();
Now code is more clear - it tells that you have multiplication table, and you want to draw it. Drawing is simple - you draw column headers and raws:
public class MultiplicationTable
{
private const int columnWidth = 5;
private string cellFormat = "{0, " + columnWidth + "}";
private int columnsCount;
private int rowsCount;
public MultiplicationTable(int columnsCount, int rowsCount)
{
this.columnsCount = columnsCount;
this.rowsCount = rowsCount;
}
public void Draw()
{
DrawColumnHeaders();
DrawRaws();
}
private void DrawColumnHeaders()
{
string title = String.Format(cellFormat + "|", "x");
Console.Write(title);
for (int i = 1; i <= columnsCount; i++)
Console.Write(cellFormat, i);
Console.WriteLine();
int tableWidth = columnWidth * columnsCount + title.Length;
Console.WriteLine(new String('-', tableWidth));
}
private void DrawRaws()
{
for (int rowIndex = 1; rowIndex <= rowsCount; rowIndex++)
DrawRaw(rowIndex);
}
private void DrawRaw(int rowIndex)
{
DrawRawHeader(rowIndex);
for (int columnIndex = 1; columnIndex <= columnsCount; columnIndex++)
DrawCell(rowIndex * columnIndex);
Console.WriteLine();
}
private void DrawRawHeader(int rowIndex)
{
Console.Write(cellFormat + "|", rowIndex);
}
private void DrawCell(int value)
{
Console.Write(cellFormat, value);
}
}