I have made a shop app for a school project
it adds goods from goods tab to factor tab
everything is working fine but I don't know how to calculate all - total price rows to make a variable that holds the price you have to pay
EDIT: now I'm getting the error in the picture
int n = dgvfactor.Rows.Count - 1;
dgvfactor.Rows.Add();
dgvfactor.Rows[n].Cells[0].Value = txtFGoodsCode.Text;
dgvfactor.Rows[n].Cells[1].Value = lblgoodsname.Text;
dgvfactor.Rows[n].Cells[2].Value = txtFAmount.Text;
dgvfactor.Rows[n].Cells[3].Value = lblprice.Text;
int amount = int.Parse(txtFAmount.Text);
int price = int.Parse(lblprice.Text);
int total = (amount * price);
lbltotal.Text = total.ToString();
dgvfactor.Rows[n].Cells[4].Value = lbltotal.Text;
var totalPrice = 0;
int rowPrice;
for (int i = 0; i < dgvfactor.Rows.Count; i++)
{
if (int.TryParse(dgvfactor.Rows[i].Cells[4].Value.ToString(), out rowPrice))
{
totalPrice += rowPrice;
}
}
lblpricetopay.Text = totalPrice.ToString();
Sorry If im mistaken here, but can't you just simply use a for-loop ?
var totalPrice = 0;
int rowPrice;
for (int i = 0; i < dgvfactor.Rows.Count; i++) {
// Note the NOT (!) new row...
if (!dgvfactor.Rows[i].IsNewRow) {
if (int.TryParse(dgvfactor.Rows[i].Cells[4].Value.ToString(), out rowPrice))
{
totalPrice += rowPrice;
}
}
}
Related
So I'm doing a practical that involves asking the user to input a score between 0 and 100. The program will keep track of the number of scores that have been entered, the total score (sum of all scores) and the average score.
To calculate the total score, I've come up of the idea of using a for loop that will cycle through my listbox and add each score to a variable (below).
int sTotal = 0;
for(int i = 0; i < lstScores.Items.Count; i++)
{
//Calculation occurs here
}
txtScoreTotal.Text = Convert.ToString(sTotal);
Thing is, I don't exactly know how to do it. I've tried searching to no avail. Any help would be greatly appreciated.
int sTotal = 0;
int Average = 0;
for(int i = 0; i < lstScores.Items.Count; i++)
{
bool result = Int16.TryParse(lstScores.Items[i],out int res);
if (result)
{
sTotale += res;
}
}
Average = sTotal / lstScores.Items.Count;
txtScoreTotal.Text = Convert.ToString(sTotal);
See this
int i = 0, result = 0;
while (i < lstScores.Items.Count)
{
result += Convert.ToInt32(lstScores.Items[i++]);
}
txtScoreTotal.Text = Convert.ToString(result);
I havent tried following, but you can try 1 line solution too
var sum = lstScores.Items.OfType<object>().Sum(x => Convert.ToInt32(x));
You need to handle exception if sum exceedes int.Max
Easiest is it to do with a foreach loop like this:
int sTotal = 0;
foreach (string item in lstScores.Items)
{
sTotal += Int32.Parse(item);
}
txtScoreTotal.Text = Convert.ToString(sTotal);
First off yes, This is a homework assignment, I've been struggling with it for 3 days, and I can't figure it out.
Basically the problem is to take a decimal amount entered by the user in a text box, I then need to take that number and break it down into currency denominations, $50, $20, $10, $5, $1 and if the amount has a decimal then into
$.25, $.10, $.05, $.01.
And I need to break this down in the lowest amount of denominations possible, for example $100 would be broken down into 2 $50 bills.
Here is what I have so far.
private void btnDispense_Click(object sender, EventArgs e)
{
decimal i;
i = decimal.Parse(txtAmountReq.Text);
decimal totalAmount = Convert.ToDecimal(txtAmountReq);
int[] denomBills = { 50, 20, 10, 5, 1 };
int[] numberOfBills = new int[5];
decimal[] denomCoins = { .25m, .10m, .05m, .01m };
int[] numberOfCoins = new int[4];
//For loop for amount of bills
for (numberOfBills[0] = 0; totalAmount >= 50; numberOfBills[0]++)
{
totalAmount = totalAmount - 50;
}
for (numberOfBills[1] = 0; totalAmount < 20; numberOfBills[1]++)
{
totalAmount = totalAmount - 20;
}
for (numberOfBills[2] = 0; totalAmount < 10; numberOfBills[2]++)
{
totalAmount = totalAmount - 10;
}
for (numberOfBills[3] = 0; totalAmount < 5; numberOfBills[3]++)
{
totalAmount = totalAmount - 5;
}
for (numberOfBills[4] = 0; totalAmount <= 0; numberOfBills[4]++)
{
totalAmount = totalAmount - 1;
}
//For loop for the amount of coins
for (numberOfCoins[0] = 0; totalAmount >= .25m; numberOfBills[0]++)
{
totalAmount = totalAmount - .25m;
}
for (numberOfBills[1] = 0; totalAmount < .10m; numberOfBills[1]++)
{
totalAmount = totalAmount - .10m;
}
for (numberOfBills[2] = 0; totalAmount < .05m; numberOfBills[2]++)
{
totalAmount = totalAmount - .05m;
}
for (numberOfBills[3] = 0; totalAmount < .01m; numberOfBills[3]++)
{
totalAmount = totalAmount - .01m;
}
txt50.Text = Convert.ToString(numberOfBills[0]);
txt20.Text = Convert.ToString(numberOfBills[1]);
txt10.Text = Convert.ToString(numberOfBills[2]);
txt5.Text = Convert.ToString(numberOfBills[3]);
txt1.Text = Convert.ToString(numberOfBills[4]);
txtQuarter.Text = Convert.ToString(numberOfCoins[0]);
txtDime.Text = Convert.ToString(numberOfCoins[1]);
txtNickel.Text = Convert.ToString(numberOfCoins[2]);
txtPenny.Text = Convert.ToString(numberOfCoins[3]);
}
Any help would be greatly appreciated.
This is very famous knapsack type problem.You might want to start exploring from here : https://en.wikipedia.org/wiki/Change-making_problem
The best way to address this problem is to find all possible combinations of change and then find the optimal solution.
Below is the code by karamana I found on codeproject.com :
//find all the combinations
private void findAllCombinationsRecursive(String tsoln,
int startIx,
int remainingTarget,
CoinChangeAnswer answer) {
for(int i=startIx; i<answer.denoms.length ;i++) {
int temp = remainingTarget - answer.denoms[i];
String tempSoln = tsoln + "" + answer.denoms[i]+ ",";
if(temp < 0) {
break;
}
if(temp == 0) {
// reached the answer hence quit from the loop
answer.allPossibleChanges.add(tempSoln);
break;
}
else {
// target not reached, try the solution recursively with the
// current denomination as the start point.
findAllCombinationsRecursive(tempSoln, i, temp, answer);
}
}
}
in order to find optimum solution :
public CoinChangeAnswer findOptimalChange(int target, int[] denoms) {
CoinChangeAnswer soln = new CoinChangeAnswer(target,denoms);
StringBuilder sb = new StringBuilder();
// initialize the solution structure
for(int i=0; i<soln.OPT[0].length ; i++) {
soln.OPT[0][i] = i;
soln.optimalChange[0][i] = sb.toString();
sb.append(denoms[0]+" ");
}
// Read through the following for more details on the explanation
// of the algorithm.
// http://condor.depaul.edu/~rjohnson/algorithm/coins.pdf
for(int i=1 ; i<denoms.length ; i++) {
for(int j=0; j<target+1 ; j++) {
int value = j;
int targetWithPrevDenomiation = soln.OPT[i-1][j];
int ix = (value) - denoms[i];
if( ix>=0 && (denoms[i] <= value )) {
int x2 = denoms[i] + soln.OPT[i][ix];
if(x2 <= target && (1+soln.OPT[i][ix] < targetWithPrevDenomiation)) {
String temp = soln.optimalChange[i][ix] + denoms[i] + " ";
soln.optimalChange[i][j] = temp;
soln.OPT[i][j] = 1 + soln.OPT[i][ix];
} else {
soln.optimalChange[i][j] = soln.optimalChange[i-1][j]+ " ";
soln.OPT[i][j] = targetWithPrevDenomiation;
}
} else {
soln.optimalChange[i][j] = soln.optimalChange[i-1][j];
soln.OPT[i][j] = targetWithPrevDenomiation;
}
}
}
return soln;
}
Link to the original code here
I have a list of ~300 objects which all have a price and a score. I need to find the best combination (i.e. highest total score) of 15 of those objects whose total price is less than X.
The most straightforward way to do this, as I see it, is to nest 15 for loops and check every possible combination, but that would take days.
Is there any 'clean' way to do this in C#?
Thanks!
It is difficult to help without an example, but if I understand the problem then this might help.
Assuming your object looks like this
public class Item
{
public int Score { get; set; }
public decimal Price { get; set; }
}
Then the following should sort you out.
var listOfObjects = new List<Item>();
var topItems = listOfObjects.Where(p => p.Price < 100).OrderByDescending(p => p.Score).Take(15);
EDIT : After all details was disclosed, the following should help
DISCLAIMER : Quick and dirty solution (sub optimal)
Create a new class
public class ItemWithRunningTotal
{
public Item Item { get; set; }
public decimal RunningTotal { get; set; }
}
Then the following should get you what you need.
var maxTotal = 1500; //for you 8000
var objects = new List<Item>()
{
new Item() {Score = 10, Price = 100},
new Item() {Score = 20, Price = 800},
new Item() {Score = 40, Price = 600},
new Item() {Score = 5, Price = 300},
};
decimal runningTotal = 0;
var newList = objects
.OrderByDescending(p => p.Score)
.Select(p =>
{
runningTotal = runningTotal + p.Price;
return new ItemWithRunningTotal()
{
Item = p,
RunningTotal = runningTotal
};
})
.OrderByDescending(p => p.RunningTotal)
.Where(p => p.RunningTotal <= maxTotal).Take(15);
What you're looking is solution for knapsack problem. There is no known way to do it fast.
You can modify dynamic solution (https://en.wikipedia.org/wiki/Knapsack_problem#0.2F1_knapsack_problem) to choose at most maxCount items like this:
public static List<Item> BestCombination(List<Item> items, int maxPrice, int maxCount)
{
var scores = new int[items.Count + 1, maxPrice + 1, maxCount + 1];
for (int i = 1; i <= items.Count; i++)
{
var item = items[i - 1];
for (int count = 1; count <= Math.Min(maxCount, i); count++)
{
for (int price = 0; price <= maxPrice; price++)
{
if (item.Price > price)
scores[i, price, count] = scores[i - 1, price, count];
else
scores[i, price, count] = Math.Max(
scores[i - 1, price, count],
scores[i - 1, price - item.Price, count - 1] + item.Score);
}
}
}
var choosen = new List<Item>();
int j = maxPrice;
int k = maxCount;
for (int i = items.Count; i > 0; i--)
{
var item = items[i - 1];
if (scores[i, j, k] != scores[i - 1, j, k])
{
choosen.Add(item);
j -= item.Price;
k--;
}
}
return choosen;
}
Keep in mind that choosing exaclty maxCount objects can give you lower total score than choosing <= maxCount objects. Eg for items [(100, 10), (200,20), (300,30), (500,80)], maxPrice = 500 and maxCount = 2 this method returns only (500,80). If you want it to return [(200,20), (300,30)], you can initialize array like this:
for (int i = 0; i <= items.Count; i++)
{
for (int price = 0; price <= maxPrice; price++)
{
for (int count = 1; count <= maxCount; count++)
{
scores[i, price, count] = int.MinValue;
}
}
}
to make sure that in scores[, , count] are sums of count scores (or MinValue). However, it still can return another number of items if there is no way to choose exactly maxCount.
Hello I need to ignore negative numbers in a sum of a DGV column. The code I am using to add the values is as follows:
private double DGVTotal()
{
double tot = 0;
int i = 0;
for (i = 0; i < dataGridView1.Rows.Count; i++)
{
tot = tot + Convert.ToDouble(dataGridView1.Rows[i].Cells["Total"].Value);
}
return tot;
}
How would I change that so if the value of the Row is a negative number to not have it be included in the sum?
Thanks!
Kor
One line change:
tot = tot + Math.Max(0, Convert.ToDouble(dataGridView1.Rows[i].Cells["Total"].Value));
Look Ma! No IF! No ternary operators! Just plain Math!
Something like this:
private double DGVTotal()
{
double tot = 0;
int i = 0;
for (i = 0; i < dataGridView1.Rows.Count; i++)
{
Double dbTemp = Convert.ToDouble(dataGridView1.Rows[i].Cells["Total"].Value);
if (dbTemp > 0)
tot = tot + dbTemp;
}
return tot;
}
Change the body of the for loop to
{
double rowValue = Convert.ToDouble(dataGridView1.Rows[i].Cells["Total"].Value);
if (rowValue > 0)
tot += rowValue;
}
for (i = 0; i < dataGridView1.Rows.Count; i++)
{
double val = Convert.ToDouble(dataGridView1.Rows[i].Cells["Total"].Value);
tot = tot + val > 0.0 ? val : 0.0;
}
i'm trying to get this program to break down a user defined amount of dollars into the fewest possible bills. i don't think my for loops are running because if i put a writeline line in them it doesn't show up when i run it.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication13
{
class Program
{
static void Main(string[] args)
{
Console.Write("Enter the amount of money: $");
int totalAmount = Convert.ToInt32(Console.ReadLine());
calculateNumberOfBills(totalAmount);
}
static void calculateNumberOfBills(int totalAmount)
{
int[] denominations = { 20, 10, 5, 1 };
int[] numberOfBills = new int[4];
for (numberOfBills[0] = 0; totalAmount < 20; numberOfBills[0]++)
{
totalAmount = totalAmount - 20;
}
for (numberOfBills[1] = 0; totalAmount < 10; numberOfBills[1]++)
{
totalAmount = totalAmount - 10;
}
for (numberOfBills[2] = 0; totalAmount < 5; numberOfBills[2]++)
{
totalAmount = totalAmount - 5;
}
for (numberOfBills[3] = 0; totalAmount <= 0; numberOfBills[3]++)
{
totalAmount = totalAmount - 1;
}
Console.WriteLine("Number of twenties" + numberOfBills[0]);
Console.WriteLine("Number of tens" + numberOfBills[1]);
Console.WriteLine("Number of fives" + numberOfBills[2]);
Console.WriteLine("Number of ones" + numberOfBills[3]);
}
}
}
Take a look at this:
for (numberOfBills[0] = 0; totalAmount >= 20; numberOfBills[0]++)
{
totalAmount = totalAmount - 20;
}
for (numberOfBills[1] = 0; totalAmount >= 10; numberOfBills[1]++)
{
totalAmount = totalAmount - 10;
}
for (numberOfBills[2] = 0; totalAmount >= 5; numberOfBills[2]++)
{
totalAmount = totalAmount - 5;
}
for (numberOfBills[3] = 0; totalAmount > 0; numberOfBills[3]++)
{
totalAmount = totalAmount - 1;
}
This is a homework question, right?
for (numberOfBills[0] = 0; totalAmount < 20; numberOfBills[0]++)
make it
for (numberOfBills[0] = 0; totalAmount >= 20; numberOfBills[0]++)
and try again :)
The center piece is the condition where the loop should run.
Sorry, at this point this is "not a real question" and should most probably be tagged as homework.
Your "smaller than" comparisons should be changed to "greater than" comparisons and you're good to go with your solution. What's happening now is an integer overflow, eventually causing your first for-loop , which was infinitely looping until then to break.
There are easier ways to solve your problem, try it with a single loop and the modulo operator).
in your "for" loops you have inverse condition => totalAmount < 20 means that it executes loop while totalAmount is less than 20 - that is the opposite of what you want.
Change it to
for(...;totalAmount > 20; ...)
Try this, a bit of less code
int amt = 73;
Dictionary<int, int> dic = new Dictionary<int, int>() {{20,0},{10,0},{5,0},{1,0}};
int[] keys =new int[dic.Count];
dic.Keys.CopyTo(keys, 0);
foreach (int i in keys)
{
if (amt >= i)
{
dic[i] = amt / i;
amt = amt % i;
}
}