C# help, overloading a method - c#

I have one last thing to add to my assignment before im finished.
This is a part of my code:
static decimal FahrToCels(int fahrenheit) //Metod för konvertering av Fahrenheit(F) till Celsius(C)
{
decimal celsius = (decimal)((fahrenheit - 32) * 5) / 9; // Matematisk uträkning för F till C.
return Math.Round (celsius, 1); //Lagrar ett decimal tal avrundat till 1 decimal och lagrar i celsius
}
static void Main(string[] args)
{
Console.Write("Vänligen ange temperatur till bastun och tryck enter: "); //skriver ut meddelande
do
int fahr = int.Parse(Console.ReadLine()); // Omvandlar string och lagrar användarens inmatning i en int fahrenheit
decimal celsius = FahrToCels(fahr); // Metoden FahrToCels konverterar inmatad temperatur till celsius och lagrar i decimal celsius
As can be seen, ive created a method, that is later used after the user is told to enter degrees in fahrenheit. The method converts the entered number to celsius.
Now the last thing im told to do is by overloading the method, make it possible for the user to enter zero(0) and by doing that randomly generate a number before that number goes into the fahrenheit to celsius converting method. Im guessing the generated numbet has to be like between 140-195 because the user needs to enter zero until the generated number equals to 73-77 after converting to celsius!
I know how to generate a random number, and i think i understand what overloading does, but im totally lost on how to do this one...

An idea would be to create a function under (or over) the method inside the class that takes no arguments. Nothing else special is required. When you want to call FahrToCels(), you have the option to call either method based on the type and quantity of the arguments.
static decimal FahrToCels ()
{
// Your code here
}

Create a new method like this
static decimal FahrToCels(string value) //note value is of type 'string'
{
//your implementation goes here, check if value is 'zero'
}
This solves your requirement to use method overloading, event though I find it a bit odd.

Apart from other possible concerns: Overloading a method has nothing to do with specific parameter values (unless you are using different types, e.g. short, int, long). In your case: "if the parameter value is 0 then return a random number" is not something solvable by overloading.
Now after reading your comment on the question; you could create a method that doesn't take any parameters static decimal FahrToCels() and call that in case you read a 0 from the input. This new method would then generate a random value and convert that.
Personal opinion: I'm not gonna comment on how reasonable that assignment is. The more standard case would be to use an if statement to decide if the input was 0 and if so generate a random value and pass that to the method you already have. But I might be missing something here.

Related

if/else if statement not working, program always uses the first if

I'm trying to do a little homework. It's for practice if statement. What's wrong with my code ? It always ends by writing "Allez à l'hôpital" even if the "temperature" variable value is less than 39.
Here is my code :
using System;
using static System.Console;
namespace E4_2
{
internal class Program
{
static void Main(string[] args)
{
string texteÀAfficher;
WriteLine("Veuillez indiquez la température du patient en celcius :");
int temperature = Convert.ToInt32(Read());
if (temperature > 39)
{
texteÀAfficher = "Allez à l'hopital";
}
else if (temperature > 38)
{
texteÀAfficher = "Prendre de l'aspirine ou de l'eau";
}
else if (temperature > 37)
{
texteÀAfficher = "Se reposer";
}
else
{
texteÀAfficher = "Prendre l'air et bien s'habiller";
}
WriteLine(texteÀAfficher);
}
}
}
The if/else statement is working.[1] That's not the problem. The simplest and most logical explanation is that the value of the temperature variable is actually larger than 39.
But you entered a temperature less than 39, right?
Well, yes, but...
You don't use the Console.Read() method properly. If you check its official documentation, you will see that its return type is int. It returns a character (or rather a Unicode character code value) as an int value. This means, Convert.ToInt32 isn't doing anything useful here, because converting an int value to an int yields just the same int value, obviously.
In consequence this means that the temperature variable contains the Unicode character code value of whatever character you typed in first. If you were to type in 38, the first character typed in is 3. The character 3 has the Unicode character code value of 51. And the value 51 is obviously larger than 39.
Since Console.Read() only reads a single character, it's not really practical (at least not in an easy manner) for inputting values with multiple characters/digits. Instead, i'd suggest to use Console.ReadLine() and parse the resulting string as an int:
string input = Console.ReadLine();
int temperature = int.Parse(input);
[1] if/else is the "bread and butter" of control flow of pretty much almost every program ever written in C#. It works, it always had, always does and always will. It just has to work. Imagine the claim in the question title of if/else not working being true. Can you imagine, almost every meaningful C# program ever written would be broken and not functioning properly if if/else were broken. That if/else is not working is a quite extraordinary claim that's just not tenable without putting real hard evidence on the table.

My code works, but I don't fully understand how

using System;
namespace SimpleweightConversion
{
public class PoundstoKilos
{
public static void Main()
{
double pounds = 0.0;
Console.Write("How many pounds? ");
double.TryParse(Console.ReadLine(), out pounds);
double kilograms = pounds * 0.453592;
Console.WriteLine("{0} pounds is equal to {1} kilograms", pounds,
kilograms);
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
}
}
I'm trying to learn C# and I created this code to convert from pounds to kilograms, I added the tryparse bit to avoid an error if the user throws something other than numbers at the program, and it works!.The only problem I have is it doesn't clearly show when does it assign the user's input to the pounds variable, because at the start, the value of the pounds variable is 0.0, but at some point, the value provided by the user is assigned to the pounds variable, or at least that's what I think is happening.
From the Microsoft Docs, the syntax for TryParse() is:
public static bool TryParse(
string s,
out double result
)
This means that if the string s is numeric, its parsed value is immediately assigned to the variable result.
In your code, you have the line double.TryParse(Console.ReadLine(), out pounds);
In this case, the input from the console is parsed to a double, and assigned to pounds if possible.
The user's input is assigned to the pounds variable within the TryParse() method.
The out modifier indicates that the argument is being passed by reference - which means that any changes to the argument (in this case, pounds) that occur within the method call will be applied to the actual variable.
It is get assigned when u take user's input using Console. ReadLine() method.
"I.e. double.TryParse(Console.ReadLine(), out pounds);"
User's input is extracted into pounds variable.
The other answers have explained your error. I thought I'd just show you how you should write your code to make it easier to understand:
public class PoundsToKilos
{
public static void Main()
{
double pounds = 0.0;
Console.Write("How many pounds? ");
if (double.TryParse(Console.ReadLine(), out pounds))
{
//`pounds` has been assigned a value
double kilograms = pounds * 0.453592;
Console.WriteLine("{0} pounds is equal to {1} kilograms", pounds, kilograms);
}
else
{
//`pounds` has NOT been assigned a value
Console.WriteLine("You didn't enter a valid number.");
}
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
}

Convert.ToInt32 user input array to int c#

I have the attached code which trys to find all 1s in an array input by the user.
The program asks the user to select the array size, then input a number of that size with some 1s in it. It then counts the number of 1s found.
I guess that the input the user gives is in the form of a string? So, if they input 12345 it would be a string with one 1 in it.
I am trying to convert the array to int32, though I don't think I fully understand why it has to be int32 either.
If somebody could help me understand this programs' workings and why I'm getting the following error I'd be thankful.
An unhandled exception of type 'System.FormatException' occurred in
mscorlib.dll Additional information: Input string was not in a correct
format.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace count1s
{
class Program
{
static void Main(string[] args)
{
int count = 0;
Console.WriteLine("Enter a number for the array length");
int limit = int.Parse(Console.ReadLine());
int[] array1s = new int[limit];
Console.WriteLine("Enter a number with some 1s in it");
for(int i=0; i<limit; i++)
{
array1s[i] = Convert.ToInt32(Console.ReadLine());
}
foreach (int number in array1s)
{
if (number == 1)
{
count++;
}
}
Console.WriteLine("The number of 1s in the array is: {0}", count);
Console.ReadLine();
}
}
}
You are getting this error because you are entering the array elements in one line.
If you enter one element on one line then program will work fine.
If you want to accept numbers on one line then you can use split function like
String []numbers = Console.ReadLine().Split(' ');
for (int i = 0; i < limit; i++)
{
array1s[i] = Convert.ToInt32(numbers[i]);
}
foreach (int number in array1s)
{
if (number == 1)
{
count++;
}
}
I don't think I fully understand why it has to be int32 either.
It doesn't have to be. That depends on your input. If the user enters a number small enough, it can also fit into a short (which is 16 bits), and you can parse the string into that.
why I'm getting the following error
Because you're trying to parse a string which isn't parse-able to a valid int value. If you're not sure the input is valid, you can use a method such as int.TryParse, which returns a boolean indicating the success or failure of the parsing:
int i = 0;
while (i < limit)
{
string value = Console.ReadLine();
int parsedValue;
if (!int.TryParse(value, out parsedValue))
{
Console.WriteLine("You've entered an invalid number. Please try again");
continue;
}
array[i] = parsedValue;
i++;
}
If you want to count all occurrences of 1, you can simply use Enumerable.Count which takes a predicate:
return array.Count(number => number == 1);
Use this as
for(int i=0; i<limit; i++)
{
int value;
var isNumber = int.TryParse(Console.ReadLine(), out value);
if(isNumber)
{
array1s[i] = value;
}
else
{
Console.WriteLine("Invalid value you have entered");
continue;
}
}
Well, now I feel like a bit of an idiot.
I tried some of your responses, thanks very much for that, and they are good. I went back and tried the code I originally posted as well and found that it does work. I just need to hit carriage return after each entry into the array.
I'll take a look at all of this properly later to find out what is going on.
Thanks again all - gotta say - was really surprised to get so many responses on here so quickly. Awesome!!
I just found a really good article on the Microsoft: DEV204x Programming with C# course I have started online. I think this will be helpful to all who follow with the same questions I had. Hopefully I'm not breaking any copyright laws or stackoverflow rules. It's a free course, so I doubt it.
Data Conversions
C# supports two inherent types of conversion (casting) for data types, implicit and explicit. C# will use implicit conversion where it can, mostly in the case when a conversion will not result in a loss of data or when the conversion is possible with a compatible data type. The following is an example of an implicit data conversion.
Converting from smaller to larger integral types:
int myInt = 2147483647;
long myLong= myInt;
The long type has a 64-bit size in memory while the int type uses 32-bits. Therefore, the long can easily accomodate any value stored in the int type. Going from a long to an int may result in data loss however and you should use explicit casting for that.
Explicit casts are accomplished in one of two ways as demonstrated with the following coe sample.
double myDouble = 1234.6;
int myInt;
// Cast double to int by placing the type modifier ahead of the type to be converted
// in parentheses
myInt = (int)myDouble;
The second option is to use the methods provided in the .NET Framework.
double myDouble = 1234.6;
int myInt;
// Cast double to int by using the Convert class and the ToInt32() method.
// This converts the double value to a 32-bit signed integer
myInt = Convert.ToInt32(myDouble);
You will find many other methods in the Convert class that cast to different integral data types such as ToBoolean(), ToByte(), ToChar(), etc.
The Convert.ToInt32() method can also be used to cast a string literal to a numeric data type. For example, you may have GUI-based application in which uses input data into text boxes. These values are string values when passed to the code in your application. Use of the above method to cast the string to numbers can help prevent exceptions in your code when trying to use the wrong data type in a specific area.
C# also provides another mechanism to deal with casting types. The use of the TryParse() method and Parse() methods can help with casting as well. These methods are attached to the types in C# rather than the Convert class. An example will help demonstrate.
// TryParse() example
bool result = Int32.TryParse(value, out number);
// Parse() example
int number = Int32.Parse(value);
In the TryParse() example, the method returns a Boolean result indicating if the conversion succeeded. In the Parse() example, if the conversion does not succeed, an exception will be thrown.

I need help instantiating multiple objects from a single method & class

C# HOMEWORK QUESTION: I am creating a console application that prompts for two integers, prompts for which math operation to perform, and returns the results. I was able to get it to work with my two operands hardcoded, and now I'm trying to instantiate two separate objects through user input instead of a hardcoded variable. I've stripped it down to the barebones code that I'm having issues with, and I suspect the problem has something to do with the way I'm creating two objects from the same method...but I'm not sure what.
Here's my main class...
public class MainModule
{
public static void Main(string[] args)
{
// get Operands
Console.WriteLine("You Will Be Entering Two Integers.\n");
//
MathUI myOperand1 = new MathUI();
int op1 = myOperand1.EnterInteger();
//
MathUI myOperand2 = new MathUI();
int op2 = myOperand2.EnterInteger();
Console.WriteLine("You chose {0} and {1}.", (int)op1, (int)op2);
Console.ReadLine();
}
}
...and the MathUI class that accepts inputs.
public class MathUI
{
public int EnterInteger()
{
Console.Write("Enter an integer: ");
int enteredInteger = Console.Read();
return (enteredInteger);
}
}
When I execute the program, I get a prompt for an integer. I enter, for instance, 3, here's my output.
You Will Be Entering Two Integers.
Enter an integer: 3
Enter an integer: You chose 51 and 13.
Math demo completed
Press <enter> to quit
When I press enter after entering the first integer, I automatically get a second integer; and when I try to output the integer values, they don't match my input.
What's going on here? Is there something wrong with the way that I'm instantiating MathUI and my two operands? Do I only need to instantiate one instance of MathUI then declare both variables under that one instance? I'm also not sure why the integer output does not match my input. All the variables are cast as int, so I should have int all the way through, right? I tried casting these as integers--(int)op1--just in case op1 was held in some internal form...but don't know what's going on there.
What am I missing?
you need to make the Console.Read a Console.ReadLine as readline is triggered by the return key.
public class MathUI
{
public int EnterInteger()
{
Console.Write("Enter an integer: ");
int enteredInteger = Convert.ToInt32(Console.ReadLine());
return (enteredInteger);
}
}
Problem is that you are using Console.Read method which returns a value after any key has been pressed. Also, result it returns is ASCII value of key pressed. In your case, you pressed 3 which has ordinal (ASCII) value of 51 in decimal system and then ENTER which has value 13. If you look at MSDN documentation, Console.Read returns an integer.
To read value user entered as a string, use Console.ReadLine method.
If you really need to read in key by key, you can use Convert.ToChar, and then ToString method to get entered key as string. Like so:
string key = Convert.ToChar(Console.ReadLine()).ToString();
Or you can use following code to read actual operand
int intOperand;
if (!int.TryParse(Console.ReadLine(), out intOperant))
Console.WriteLine("You pressed non-numeric key");
Use Console.ReadLine instead of Console.Read. With Console.Read, the return character is being passed as input to the second Read call.
Also note that the int that is returned by Console.Read is not parsing a numeric number, it is giving you the Unicode character value of the entered char. This is why you are getting the "wrong" numbers.
You need to use Console.ReadLine and parse the string result like so:
public class MathUI
{
public int EnterInteger()
{
Console.Write("Enter an integer: ");
int enteredInteger = int.Parse(Console.ReadLine());
return (enteredInteger);
}
}
A couple other notes for your consideration:
There's no need to cast the values in the Console.WriteLine call.
You can make the MathUI class and EnterInteger method static.

Making a program do absolutely nothing when certain data or wrong answer is put in

I have this crazy idea, I would like a program to not execute anything if the wrong data is put into the console. Such as the alphabet, weird characters. All I want is decimal numbers and a period to be accepted. If the wrong data is typed in, I want the program to STAY there and do absolutely nothing after you hit enter.
My mindset thinks:
if (sum != decimal)
{
// Don't do anything, just leave it as is.
code I have no clue about.
}
Now, you must be thinking, you can't use datatypes for an if statement! Maybe you can, but its not working for me. I'm sorry I'm a big noob.
try
{
Console.WriteLine("Put in the price of the product");
string input = Console.ReadLine();
decimal sum = Convert.ToDecimal(input);
if (sum <= 100)
{
decimal totalprice = sum * .90m;
Console.WriteLine("Your final price is {0:0:00}", totalprice);
}
}
catch
{
}
I was also thinking maybe a try and catch statement would work too, but again, I have no clue what to put in that either.
If your answers could be noob-safe and explained. (Because I want to learn the concept of how this stuff works) that would be nice.
A visual example:
When you hit enter, nothing happens but when you put in the correct datatype, the program will continue.
Datatypes are not written to console. Only strings could be retrieved from console input. What type has string "2" - decimal, int, byte, string? All you can do is try to parse some type from your input string:
Int32.TryParse("2", out value)
For your case:
Console.WriteLine("Put in the price of the product");
string input = Console.ReadLine();
decimal sum;
if (!Decimal.TryParse(input, out sum))
{
Console.WriteLine("Decimal number cannot be parsed from your input.");
return;
}
if (sum <= 100)
Console.WriteLine("Your final price is {0:0:00}", sum * 0.90M);
UPDATE
Decimal.TryParse - Converts the string representation of a number to its Decimal equivalent. A return value indicates whether the conversion succeeded or failed. It does not throws an exception if conversion failed.
! Operator - it is NOT operator. The logical negation operator (!) is a unary operator that negates its operand. It is defined for bool and returns true if and only if its operand is false.
So if (!Decimal.TryParse(input, out sum)) verifies if conversion was NOT successful. Then I put a sample message for user and exited from method (if it was your Main method, then program will terminate. But this all is out of your initial question about parsing strings.
Try this (note the while/break pairing):
while (true)
{
string input = Console.ReadLine();
decimal sum;
if (Decimal.TryParse(input, out sum) == true)
{
if (sum <= 100)
{
decimal totalprice = sum * .90m;
Console.WriteLine("Your final price is {0:0:00}", totalprice);
break; // break out of while
}
}
}
The conversion function you are using will I believe throw an exception if it cannot convert the string passed to the requested type. Generally, exceptions should be avoided for controlling program flow, and reserved for truly unexpected situations. Instead, you should look to using a method that doesn't throw an exception, but instead returns a value to indicate success or failure. With this in ind you could try:
try
{
Console.WriteLine("Put in the price of the product");
decimal sum;
// Repeat forever (we'll break the loop once the user enters acceptable data)
while (true)
{
string input = Console.ReadLine();
// Try to parse the input, if it succeeds, TryParse returns true, and we'll exit the loop to process the data.
// Otherwise we'll loop to fetch another line of input and try again
if (decimal.TryParse(input, out sum)) break;
}
if (sum <= 100)
{
decimal totalprice = sum * .90m;
Console.WriteLine("Your final price is {0:0:00}", totalprice);
}
}
catch
{
}

Categories