I am studying programming and I am very beginner (started 2 months ago).
I am doing a c# exercise for maths calculation. Our professor used a if ... else (embricated) loops to do the exercise. I wanted to use a switch case but I am struggling with the local variables.
I understand the issue: case 2 and 3 does not "know" the variables totalNumber and nbrSubAssy is as they come from case 1 and case 2, then they are detected as not assigned.
If I still want to use a switch case, what could I do to solve it?
using System;
namespace Denombrements
{
class Program
{
static long IntMultiplication(int startValue, int endValue)
{
long multiplication = 1;
for (int k = startValue; k <= endValue; k++)
multiplication *= k;
return multiplication;
}
static int UserSelection(String message)
{
int number = 0;
Console.Write(message);
try
{
number = int.Parse(Console.ReadLine());
Console.WriteLine();
}
catch
{
Console.WriteLine();
Console.WriteLine("Wrong input, enter an integer");
}
return number;
}
static void Main(string[] args)
{
char choice = '1';
while (choice != '0')
{
Console.WriteLine("Permutation ...................... 1");
Console.WriteLine("Arrangement ...................... 2");
Console.WriteLine("Combination ...................... 3");
Console.WriteLine("Quit ............................. 0");
Console.Write("Choice : ");
choice = Console.ReadKey().KeyChar;
Console.WriteLine();
switch(choice)
{
case '0':
Environment.Exit(0);
break;
case '1':
int totalNumber = UserSelection("Total number of elements to be taken into account");
long permutation = IntMultiplication(1, totalNumber);
Console.WriteLine(totalNumber + "! = " + permutation);
break;
case '2':
int nbrSubAssy = UserSelection("Total number of elements in the subassy to be taken into account");
long arrangement = IntMultiplication(totalNumber - nbrSubAssy + 1, totalNumber);
Console.WriteLine("A(" + totalNumber + "/" + nbrSubAssy + ") = " + arrangement);
break;
case '3':
long combination = arrangement / IntMultiplication(1, nbrSubAssy);
Console.WriteLine("C(" + totalNumber + "/" + nbrSubAssy + ") = " + combination);
break;
default:
Console.WriteLine("Wrong input");
break;
}
}
Console.ReadLine();
}
}
}
Declare your variable before While loop and it will keep the value of it for all the life of LOOP and you could access the old values
char choice = '1';
int nbrSubAssy = 0;
int totalNumber = 0;
long arrangement = 0;
while (choice != '0')
{
// code ...
switch (choice)
{
case '0':
Environment.Exit(0);
break;
case '1':
totalNumber = UserSelection("Total number of elements to be taken into account");
long permutation = IntMultiplication(1, totalNumber);
Console.WriteLine(totalNumber + "! = " + permutation);
break;
case '2':
nbrSubAssy = UserSelection("Total number of elements in the subassy to be taken into account");
arrangement = IntMultiplication(totalNumber - nbrSubAssy + 1, totalNumber);
Console.WriteLine("A(" + totalNumber + "/" + nbrSubAssy + ") = " + arrangement);
break;
case '3':
long combination = arrangement / IntMultiplication(1, nbrSubAssy);
Console.WriteLine("C(" + totalNumber + "/" + nbrSubAssy + ") = " + combination);
break;
default:
Console.WriteLine("Wrong input");
break;
}
}
or in my opinion the better solution you could ask for the value in every case you need them
Only if(artikelen > 50) works. I think I know why, but I don't know how to resolve the problem.
switch function, but I don't know how to use "< or >" in that function.
C#:
private void button1_Click(object sender, EventArgs e) {
double bruto = double.Parse(textBox1.Text);
double artikelen = double.Parse(textBox2.Text);
double loon;
if (artikelen < 10) {
double twee = bruto + (bruto / 100 * 2);
loon = twee;
textBox3.Text = loon.ToString();
}
if (artikelen >= 10 && bruto < 50) {
double vijf = bruto + (bruto / 100 * 5);
loon = vijf;
textBox3.Text = loon.ToString();
}
if (artikelen > 50) {
double tien = bruto + (bruto / 100 * 10);
loon = tien;
textBox3.Text = loon.ToString();
}
}
private void textBox1_TextChanged(object sender, EventArgs e) {
}
You can use less than or greater than in a switch statement with C# 7:
switch (value)
{
case var _ when value < 10:
// something
break;
case var _ when (value >= 10 && value < 50):
// something
break;
case var _ when value > 50:
// something
break;
default:
// something
break;
}
For multiple inputs, look at tuple patterns in C# 8.
Looks like a lot of duplicate code.
I'd split that into:
decimal GetFactor( decimal artikelen )
{ // order is important!
if( artikelen >= 50 ) return 10m;
if( artikelen >= 10 ) return 5m;
return 2m;
}
To get the factor. Then do the math:
decimal GetLoon( decimal bruto, decimal factor ) // With factor from above result
{
return bruto + (bruto / 100m * factor);
}
Resulting in
textBox3.Text = GetLoon( bruto, GetFactor( artikelen) ).ToString();
Some additional points:
I assume these are monetary amounts. => Use decimal, not floating point!
Always validate user input. What if a value cannot be parsed? What if artikelen < 0 ?
I'm making a program to convert any input amount into denominations of twenties, tens, fives, and ones. Here's what I'm having trouble with:
int twenties = dollar/20;
int tens = twenties/2;
int fives = tens/2;
int ones = fives/5;
Dollar is the input amount, the twenties expression seems to be the only one that comes out right. For example: I input 161 and it comes out as 161 is equal to 8 twenties, 4 tens, 2 fives, and 0 ones. But it should be coming out as 161 is equal to 8 twenties, 0 tens, 0 fives, and 1 ones. I know there is a really simple answer to this but I'm just not getting it, thanks guys.
You need to work with the remainder after removing those denominations. The easiest way to get the remainder is the modulus operator, like this...
int dollar = 161;
int twenties = dollar / 20;
int remainder = dollar % 20;
int tens = remainder / 10;
remainder = remainder % 10;
int fives = remainder / 5;
remainder = remainder % 5;
int ones = remainder;
The above approach does not modify the original amount. By refactoring that into a method, it makes it easier to reuse with different denominations:
public int RemoveDenomination(int denomination, ref int amount)
{
int howMany = amount / denomination;
amount = amount % denomination;
return howMany;
}
...which you could use like this...
int dollar = 161;
int hundreds = RemoveDenomination(100, ref dollar);
int fifties = RemoveDenomination(50, ref dollar);
int twenties = RemoveDenomination(20, ref dollar);
int tens = RemoveDenomination(10, ref dollar);
int fives = RemoveDenomination(5, ref dollar);
int ones = dollar;
This approach does modify the dollar value. So if you don't want to change it, make a copy of it in another variable, and work on the copy.
You have to use the remainder and subtract until the remainder becomes 0;
int amount = 161, temp = 0;
int[] denomination = { 20, 10, 5, 1 }; // you can use enums also for
// readbility
int[] count = new int[denomination.Length];
while (amount > 0)
{
count[temp] = amount / denomination[temp];
amount -= count[temp] * denomination[temp];
temp ++;
}
Another option is to use linq:
int[] denominations = new [] { 20, 10, 5, 1 };
List<int> result =
denominations
.Aggregate(new { Result = new List<int>(), Remainder = 161 }, (a, x) =>
{
a.Result.Add(a.Remainder / x);
return new { a.Result, Remainder = a.Remainder % x };
})
.Result;
That returns a list with the values { 8, 0, 0, 1 }.
Alternatively you could do this:
public static Dictionary<string, int> Denominations(int amount)
{
var denominations = new Dictionary<string, int>();
denominations["twenties"] = amount / 20;
amount = amount % 20;
denominations["tens"] = amount / 10;
amount = amount % 10;
denominations["fives"] = amount / 5;
amount = amount % 5;
denominations["ones"] = amount;
return denominations;
}
This console app illustrates a possible solution:
internal static class Program
{
internal static void Main()
{
var results = GetDenominationValues();
foreach (var result in results)
{
Console.WriteLine($"{result.Key} - {result.Value}");
}
Console.ReadLine();
}
private static Dictionary<int, int> GetDenominationValues()
{
var amount = 161;
var denominations = new[] { 20, 10, 5, 1 };
var results = new Dictionary<int, int>();
foreach (var denomination in denominations)
{
results.Add(denomination, amount / denomination);
amount = amount % denomination;
if (amount == 0) break;
}
return results;
}
}
The key difference is in the line:
amount = amount % denomination;
Which uses the remainder of the previous division in the subsequent calculations.
If the division is greater than zero pass on the remainder (using the modulo operator, %) else pass on the original value to the next division in line. Repeat until no more division left.
Also, divide tens with 10, fives with 5 and ones with 1.
Please use below function that returns dictionary
public static Dictionary<string, int> Denominations(int amount)
{
Dictionary<string, int> denominations = new Dictionary<string, int>() { { "twenties", 0 }, { "tens", 0 }, { "fives", 0 }, { "ones", 0 } };
int twenties, tens, fives, ones;
if (amount >= 20)
{
twenties = amount/20;
denominations["twenties"] = twenties;
amount -= twenties * 20;
}
if (amount >= 10)
{
tens = amount/10;
denominations["tens"] = tens;
amount -= tens * 10;
}
if (amount >= 5)
{
fives = amount/5;
denominations["fives"] = fives;
amount -= fives * 5;
}
if (amount >= 1)
{
ones = amount;
denominations["ones"] = ones;
}
return denominations;
}
You want Code number to text ?
MoneyExt mne = new MoneyExt();
string textamount;
textamount = mne.ConvertNumberToENG(10000);
using System;
public class MoneyExt
{
public string ConvertNumberToENG(int amount)
{
var dollars, cents, temp;
var decimalPlace, count;
string[] place = new string[10];
place[2] = " Thousand ";
place[3] = " Million ";
place[4] = " Billion ";
place[5] = " Trillion ";
// String representation of amount.
amount = amount.Trim();
amount = amount.Replace(",", "");
// Position of decimal place 0 if none.
decimalPlace = amount.IndexOf(".");
// Convert cents and set string amount to dollar amount.
if (decimalPlace > 0)
{
cents = GetTens(ref amount.Substring(decimalPlace + 1).PadRight(2, "0").Substring(0, 2));
amount = amount.Substring(0, decimalPlace).Trim();
}
count = 1;
while (amount != "")
{
temp = GetHundreds(amount.Substring(Math.Max(amount.Length, 3) - 3));
if (temp != "")
dollars = temp + place[count] + dollars;
if (amount.Length > 3)
amount = amount.Substring(0, amount.Length - 3);
else
amount = "";
count = count + 1;
}
switch (dollars)
{
case "One":
{
dollars = "One Bath";
break;
}
default:
{
dollars = dollars + " Bath";
break;
}
}
// Select Case cents
// ' Case ""
// ' cents = " and No Cents"
// Case "One"
// cents = " and One Satang"
// Case Else
// cents = " and " & cents & " Satang"
// End Select
ConvertNumberToENG = dollars + cents;
}
// Converts a number from 100-999 into text
public string GetHundreds(string amount)
{
string Result;
if (!int.Parse(amount) == 0)
{
amount = amount.PadLeft(3, "0");
// Convert the hundreds place.
if (amount.Substring(0, 1) != "0")
Result = GetDigit(ref amount.Substring(0, 1)) + " Hundred ";
// Convert the tens and ones place.
if (amount.Substring(1, 1) != "0")
Result = Result + GetTens(ref amount.Substring(1));
else
Result = Result + GetDigit(ref amount.Substring(2));
GetHundreds = Result;
}
}
// Converts a number from 10 to 99 into text.
private string GetTens(ref string TensText)
{
string Result;
Result = ""; // Null out the temporary function value.
if (TensText.StartsWith("1"))
{
switch (int.Parse(TensText))
{
case 10:
{
Result = "Ten";
break;
}
case 11:
{
Result = "Eleven";
break;
}
case 12:
{
Result = "Twelve";
break;
}
case 13:
{
Result = "Thirteen";
break;
}
case 14:
{
Result = "Fourteen";
break;
}
case 15:
{
Result = "Fifteen";
break;
}
case 16:
{
Result = "Sixteen";
break;
}
case 17:
{
Result = "Seventeen";
break;
}
case 18:
{
Result = "Eighteen";
break;
}
case 19:
{
Result = "Nineteen";
break;
}
default:
{
break;
}
}
}
else
{
switch (int.Parse(TensText.Substring(0, 1)))
{
case 2:
{
Result = "Twenty ";
break;
}
case 3:
{
Result = "Thirty ";
break;
}
case 4:
{
Result = "Forty ";
break;
}
case 5:
{
Result = "Fifty ";
break;
}
case 6:
{
Result = "Sixty ";
break;
}
case 7:
{
Result = "Seventy ";
break;
}
case 8:
{
Result = "Eighty ";
break;
}
case 9:
{
Result = "Ninety ";
break;
}
default:
{
break;
}
}
Result = Result + GetDigit(ref TensText.Substring(1, 1)); // Retrieve ones place.
}
GetTens = Result;
}
// Converts a number from 1 to 9 into text.
private string GetDigit(ref string Digit)
{
switch (int.Parse(Digit))
{
case 1:
{
GetDigit = "One";
break;
}
case 2:
{
GetDigit = "Two";
break;
}
case 3:
{
GetDigit = "Three";
break;
}
case 4:
{
GetDigit = "Four";
break;
}
case 5:
{
GetDigit = "Five";
break;
}
case 6:
{
GetDigit = "Six";
break;
}
case 7:
{
GetDigit = "Seven";
break;
}
case 8:
{
GetDigit = "Eight";
break;
}
case 9:
{
GetDigit = "Nine";
break;
}
default:
{
GetDigit = "";
break;
}
}
}
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do you convert Byte Array to Hexadecimal String, and vice versa?
I need an efficient and fast way to do this conversion. I have tried two different ways, but they are not efficient enough for me. Is there any other quick method to accomplish this in a real-time fashion for an application with huge data?
public byte[] StringToByteArray(string hex)
{
return Enumerable.Range(0, hex.Length / 2).Select(x => Byte.Parse(hex.Substring(2 * x, 2), NumberStyles.HexNumber)).ToArray();
}
The above one felt more efficient to me.
public static byte[] stringTobyte(string hexString)
{
try
{
int bytesCount = (hexString.Length) / 2;
byte[] bytes = new byte[bytesCount];
for (int x = 0; x < bytesCount; ++x)
{
bytes[x] = Convert.ToByte(hexString.Substring(x * 2, 2), 16);
}
return bytes;
}
catch
{
throw;
}
If you really need efficiency then:
Don't create substrings
Don't create an iterator
Or, and get rid of try blocks which only have a catch block which rethrows... for simplicity rather than efficiency though.
This would be a pretty efficient version:
public static byte[] ParseHex(string hexString)
{
if ((hexString.Length & 1) != 0)
{
throw new ArgumentException("Input must have even number of characters");
}
int length = hexString.Length / 2;
byte[] ret = new byte[length];
for (int i = 0, j = 0; i < length; i++)
{
int high = ParseNybble(hexString[j++]);
int low = ParseNybble(hexString[j++]);
ret[i] = (byte) ((high << 4) | low);
}
return ret;
}
private static int ParseNybble(char c)
{
// TODO: Benchmark using if statements instead
switch (c)
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return c - '0';
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
return c - ('a' - 10);
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
return c - ('A' - 10);
default:
throw new ArgumentException("Invalid nybble: " + c);
}
return c;
}
The TODO refers to an alternative like this. I haven't measured which is faster.
private static int ParseNybble(char c)
{
if (c >= '0' && c <= '9')
{
return c - '0';
}
c = (char) (c & ~0x20);
if (c >= 'A' && c <= 'F')
{
return c - ('A' - 10);
}
throw new ArgumentException("Invalid nybble: " + c);
}
I took the benchmarking code from the other question, and reworked it to test the hex to bytes methods given here:
HexToBytesJon: 36979.7 average ticks (over 150 runs)
HexToBytesJon2: 35886.4 average ticks (over 150 runs)
HexToBytesJonCiC: 31230.2 average ticks (over 150 runs)
HexToBytesJase: 15359.1 average ticks (over 150 runs)
HexToBytesJon is Jon's first version, and HexToBytesJon2 is the second variant.
HexToBytesJonCiC is Jon's version with CodesInChaos's suggested code.
HexToBytesJase is my attempt, based on both the above but with alternative nybble conversion which eschews error checking, and branching:
public static byte[] HexToBytesJase(string hexString)
{
if ((hexString.Length & 1) != 0)
{
throw new ArgumentException("Input must have even number of characters");
}
byte[] ret = new byte[hexString.Length/2];
for (int i = 0; i < ret.Length; i++)
{
int high = hexString[i*2];
int low = hexString[i*2+1];
high = (high & 0xf) + ((high & 0x40) >> 6) * 9;
low = (low & 0xf) + ((low & 0x40) >> 6) * 9;
ret[i] = (byte)((high << 4) | low);
}
return ret;
}
As a variant of Jon's if based ParseNybble:
public static byte[] ParseHex(string hexString)
{
if ((hexString.Length & 1) != 0)
{
throw new ArgumentException("Input must have even number of characters");
}
byte[] ret = new byte[hexString.Length / 2];
for (int i = 0; i < ret.Length; i++)
{
int high = ParseNybble(hexString[i*2]);
int low = ParseNybble(hexString[i*2+1]);
ret[i] = (byte) ((high << 4) | low);
}
return ret;
}
private static int ParseNybble(char c)
{
unchecked
{
uint i = (uint)(c - '0');
if(i < 10)
return (int)i;
i = ((uint)c & ~0x20u) - 'A';
if(i < 6)
return (int)i+10;
throw new ArgumentException("Invalid nybble: " + c);
}
}
I am building a game of BlackJack and the main class for it is having a problem. This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public class blackjack
{
static string[] playercards = new string[11];
static string hitstay = "";
static int total = 0, count = 1, dealertotal = 0;
static Random cardshuffler = new Random();
static Form1 f1 = new Form1();
Form1.ControlCollection
static void start()
{
dealertotal = cardshuffler.Next(15, 22);
playercards[0] = deal();
playercards[1] = deal();
bj();
}
private static void hit()
{
count += 1;
playercards[count] = deal();
f1.textBox2("you were dealed a(n) " + playercards[count] + ".your new total is " + total + ".");
if (total.Equals(21))
{
f1.textBox2("you got blackjack! the dealer's total was " + dealertotal + ".would you like to play again?");
playagain();
}
else if (total > 21)
{
f1.textBox2("you busted, therefore you lost. sorry. the dealer's total was " + dealertotal + ".would you like to play again? y/n");
playagain();
}
else if (total < 21)
{
do
{
f1.textBox2("would you like to hit or stay?");
hitstay = Console.ReadLine();
} while (!hitstay.Equals("hit") && !hitstay.Equals("stay"));
bj();
}
}
private static string deal()
{
string Card = "";
int cards = cardshuffler.Next(1, 14);
switch (cards)
{
case 1: Card = "Two"; total += 2;
break;
case 2: Card = "Three"; total += 3;
break;
case 3: Card = "Four"; total += 4;
break;
case 4: Card = "Five"; total += 5;
break;
case 5: Card = "Six"; total += 6;
break;
case 6: Card = "Seven"; total += 7;
break;
case 7: Card = "Eight"; total += 8;
break;
case 8: Card = "Nine"; total += 9;
break;
case 9: Card = "Ten"; total += 10;
break;
case 10: Card = "Jack"; total += 10;
break;
case 11: Card = "Queen"; total += 10;
break;
case 12: Card = "King"; total += 10;
break;
case 13: Card = "Ace"; total += 11;
break;
}
return Card;
}
static void bj()
{
if (hitstay.Equals("hit"))
{
hit();
}
else if (hitstay.Equals("stay"))
{
if (total > dealertotal && total <= 21)
{
Form1.textBox2.show("you won! the dealer busted with " + dealertotal + " as their total" + "your total was " + total);
playagain();
}
else if (total < dealertotal)
{
Form1.textBox2.show("sorry, you lost! the dealer's total was " + dealertotal );
playagain();
}
}
}
private static void playagain()
{
}
}
}
The error is in Line 21, Column 9.
The error is actually on line 17 - this identifier is hanging out to dry:
Form1.ControlCollection
Either you meant to declare a field or this code shouldn't be there. This code is causing a error later on since the parser is looking for a field name to go with the type you have put there and assumes that your static Main method is the identifier that goes with it.
static Form1 f1 = new Form1();
Form1.ControlCollection // What is this? You forgot to write something there?
static void start()
The compiler thinks that there is a declaration which starts with "Form1.ControlCollection" and continues with "static void start()".