Suggestions on a method? [closed] - c#

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am just starting to program in C#, so I am a beginner, I've been practicing some codes and I would like your opinion on something.
I have a flying direction for a plane, e.g. ''London - Berlin'' (direction). I want to create a method that will return the first and the last consonant of the plane's starting point (London), and the first and the last consonant of the plane's destination (Berlin). I have written this, so I would like to know if it's ok, or if you have some suggestions:
public class Flight
{
private string direction;
public Flight(string direction)
{
this.direction = direction;
}
public string Consonants()
{
string starting = direction.Split('-')[0];
string destination = direction.Split('-')[1];
string startConsonants = starting.ToUpper().Replace("A", "").Replace("E", "").Replace("I", "").Replace("O", "").Replace("U", "");
string destConsonants = destination.ToUpper().Replace("A", "").Replace("E", "").Replace("I", "").Replace("O", "").Replace("U", "");
return string.Format("{0}{1}-{2}{3}", startConsonants[0].ToString(), startConsonants[startConsonants.Length-1].ToString(), destConsonants[0].ToString(), destConsonants[destConsonants.Length-1].ToString());
}
}

Here are some suggestions:
1 - First point is logical. If you pass the string "London-Lebanon" the output is LN-LN which I consider invalid. With your version, you could also get an error if you pass "London-UAE".
2 - Your constructor is requiring an argument but it is not clear why. I'd suggest you pass the argument to the method that uses it and check if the argument is valid before processing as shown below.
3 - The split is repeated twice for no reason.
4 - You repeat the ToString() several times even on string arguments.
5 - You could define a private method to do the formatting. This prevents errors in case you change the rules.
Here is my version incorporating the above points (except the first):
class Flight
{
public string Consonants(string direction)
{
string[] words = direction.Split('-');
// check if the separator is missing
if (words.Length!=2) return string.Empty; //missing separator error
return string.Format("{0}-{1}", Replacer(words[0]), Replacer(words[1]));
}
private string Replacer(string arg)
{
string abr= arg.ToUpper().Replace("A", string.Empty).Replace("E", string.Empty).Replace("I", string.Empty).Replace("O", string.Empty).Replace("U", string.Empty);
if (abr.Length < 2)
throw new Exception(string.Format("processing error in Replacer input {0} outpur {1}", arg, abr)); // example if you pass: UAE
return string.Format("{0}{1}", abr[0], abr[abr.Length - 1] );
}
}

If you don't mind the upper/lower case distinction then you could use Linq to extract the info required
public string Consonants()
{
string starting = direction.Split('-')[0];
string destination = direction.Split('-')[1];
char[] cs = new char[] {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'};
string startFirst = starting.ToUpper().ToCharArray().First(x => cs.Contains(x)).ToString();
string startLast = starting.ToUpper().ToCharArray().Last(x => cs.Contains(x)).ToString();
string destFirst = destination.ToUpper().ToCharArray().First(x => cs.Contains(x)).ToString();
string destLast = destination.ToUpper().ToCharArray().Last(x => cs.Contains(x)).ToString();
return string.Format("{0}{1}-{2}{3}", startFirst, startLast, destFirst, destLast);
}

Related

How to debug why I am not getting the right output from a C# program? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am new to C# but I have learned Java for a year and I found C# almost similar. I am trying to make a program where the output is like this
My
My Name
My Name Is
My Name Is Ahan
and the program I have written is this
class Program
{
static void Main(string[] args)
{
string str1 = "My Name Is Ahan";
int i = 0 , length = str1.Length;
Console.WriteLine(length);
for(; i<length; i++ )
{
char ch = str1[i];
if (ch == ' ')
{
int catchnum = str1.IndexOf(ch);
string displayValue = str1.Substring(0, catchnum);
Console.WriteLine(displayValue);
}
else;
}
Console.ReadLine();
}
}
Something like this?
static void Main(string[] args)
{
string str1 = "My Name Is Ahan";
string[] words = str1.Split(' ');
for (int i=0;i<words.Length;i++)
{
var selectedWords = words.Take(i + 1);
Console.Write($"{string.Join(" ", selectedWords)} ");
}
}
I think your problem is here:
int catchnum = str1.IndexOf(ch);
Within the loop you're always finding the index of the first space. You already have the index of the current space when you find it, so you could just do:
if (ch == ' ')
{
string displayValue = str1.Substring(0, i);
Console.WriteLine(displayValue);
}
I would also note that C# and Java are extremely similar for these basic operations - the same code would behave identically in Java with only minor syntax differences. Certainly the code could be simpler by using some basic library functions (like string.Split and Linq) that would be different between the two platforms, but that's not the issue here.
In other words, your errors aren't due to translation between Java and C# - they're basic logic errors that would have manifested in any programming language.

How can I get return value from int method inside main class [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I'm new in C#. I want to show my return values from my MyApp method.
public int MyApp(string strFirst, string strSecond)
{
if (strFirst.Equals(strSecond))
{
return 0;
}
for (int i = 0; i < strFirst.Length; i++)
{
string temp = strFirst.Substring(0, strFirst.Length - 1);
temp = strFirst[strFirst.Length - 1] + temp;
strFirst = temp;
if (strFirst.Equals(strSecond))
{
return i + 1;
}
}
return -1;
}
If you do not call Console.WriteLine(), nothing will be printed to the console.
So do:
Console.WriteLine(calc.MyApp("try", "yrt"));
And we usually name methods with descriptive verbs - so your MyApp should become Calculate.
Whereas classes should be named with nouns - so your Calculate should become MyApp.
That way, your code is more expressive:
var app = new MyApp();
Console.WriteLine(app.Calculate("try", "yrt"));
you can use this:
class Program
{
static void Main(string[] args)
{
Calculate calc = new Calculate();
int result = calc.MyApp("try", "yrt");
Console.WriteLine(result);
}
}
The issue is on this line:
calc.MyApp("try", "yrt");
You are calling your MyApp method, but you are not storing or using the result.
Storing the result in a variable is useful if you intend to use the result for other things:
//Store the result
var result = calc.MyApp("try", "yrt");
//Display the result
Console.Writeline(result);
You can also just pass the expression (the call to method MyApp) as an argument to the Writeline method:
Console.Writeline(calc.MyApp("try", "yrt"));
The runtime will execute the call to your method and use the result as the argument of the call to method Writeline.
Either way works. I personally would recommend using a variable if you are just getting started. Inline calls save space and can be more performant but they also make debugging harder.
If you use Console.WriteLine() and it always returns -1 where it shouldn't your problem lies with the code in the MyApp() Method.
The real problem is that you are rotating your first string and not turning it around.
So, if your first string is "hello" and your second string is "olleh" - for each iteration you will get the following for your first string:
ohell
lohel
llohe
elloh
hello
You will never get "olleh"

How do I make program with c# to check to see if a word is a palindrome? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
so i'm trying to make a program (text based) that can scan a word you type into it to see if it's a palindrome or not so just a true or false outcome i'm a beginner with c# so please help me out!
So far this is all i have done.
//Name space
namespace PalindromeChecker
{
//Class
class Program
{
//Function
static void Main(string[] args)
{
Console.WriteLine("Type the word");
ConsoleKeyInfo Keyinfo = Console.Readkey();
}
}
}
A palindrome is a sequence of characters that is the same whether read forward or in in reverse. So to determine if a string is a palindrome, we can compare the string with its reverse, it is one.
So how can you create a reverse of a string? If you look at the String definition, you'll see it implements IEnumerable. Now the System.Linq namespace offers the IEnumerable.Reverse method. This can be used to reverse a string:
var str = "oxo";
var reversed = str.Reverse();
However, this returns an enumeration of char, not a string. So string.Concat is needed to turn reversed into a string. Having done that, we now have:
var str = "oxo";
var reversed = string.Concat(str.Reverse());
To test if they are the same, simply compare them:
if (str == reversed)
{
// we have a palindrome
}
A "gotcha here is that if str is null, you'll get a null exception with str.Reverse. That can be handled with a null check. So we can then simplify the whole thing down to:
if (str != null && str == string.Concat(str.Reverse()))
{
// we have a palindrome
string word = "hi"; ;
char[] wordArray = word.ToCharArray();
char[] revWordArray = wordArray.Reverse().ToArray();
int count = 0;
for (int i1 = 0; i1 < wordArray.Length; i1++)
{
if (wordArray[i1] == revWordArray[i1])
{
count++;
}
}
if (count == wordArray.Length)
{
bool a = true;
}

TryParse dilemma-Dealing with out parameters [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I never liked out and ref parameters.When I see them in action they give me a feeling that something is messy about the design.
I thought that the only exception was the so called TryXXX pattern that returns a boolean as the function result (whether everything was fine or something went wrong) and an out parameter for the real result, until I read this article today and It made me think if there's a better pattern to implement this kind of methods.
I thought that we could either have a function that returns more than one result(or as the article says a tuple)
Tuple<Exception,T> TryParseT(object obj)
or a function that accepts a callback function for success :
void TryParseT(object obj,Action<T> success)
The question is , which one is better from a functional design point of view ?
UPDATE :
To rephrase my question , I want to know which of these two functions more complies with Functional Programming principles and why ?
Essentially the problem is that to follow the functional programming approach you should always provide a return value for an input value. So the returning void route isn't the way to go. You need to return a value that can represent success (and hold the successful result) and failure (and hold no result).
The closest to that is where you have returned a Tuple which includes the exception. However you then don't have the 'infrastructure' to deal with the Tuple reliably once you've got it. So the code scaffolding around it will be repeated.
Take a look at this library language-ext. It deals with improving the out problem for TryParse using its implementation of Option<T>.
string inp = "123";
// Attempts to parse the value, uses 0 if it can't
int value1 = parseInt(inp).IfNone(0);
// Functional alternative to above
// Attempts to parse the value, uses 0 if it can't
int value2 = ifNone(parseInt(inp), 0);
// Attempts to parse the value and then pattern matches the result
int value3 = parseInt(inp).Match(
Some: x => x * 2,
None: () => 0
);
// Functional alternative to above
// Attempts to parse the value and then pattern matches the result
int value4 = match( parseInt(inp),
Some: x => x * 2,
None: () => 0
);
The library also allows you to just check that something is valid:
if( parseInt(inp) )
return 1;
else
return 0;
And allows for comparisons without actually extracting the value:
if( parseInt(inp) == 123 )
return 123;
else
return 0;
As well as logical operations:
var allValid = parseInt(x) && parseInt(y) && parseInt(z);
var someValid = parseInt(x) || parseInt(y) || parseInt(z);
And finally LINQ expressions which can often remove the need for if-then-else or matching:
var res = from x in parseInt(inp1)
from y in parseInt(inp2)
from z in parseInt(inp3)
select x + y + z;
It also has TryGetValue extensions for IDictionary, IReadOnlyDictionary, IImmutableDictionary and IImmutableSet that instead return Option<T> and can be used as above.
The most elegant method is
int Parse(string value)
The Tryxxxx methods only exist for an implementation detail named performance. If you are seeking elegance you can use the Parse method and handle any errors by failing fast.
You can instead return a tuple but this will cost an additional allocation on the heap since Tuple is a reference type.
A better solution in terms of performance (if you care) would be aKeyValuePair. But it hides (like tuple) the semantics behind generic data types which is not optimal for code clarity. A better way to signal failure than by defining some convention that the first bool of the tuple contains the failure state is by defining your own data type.
struct ParseResult<T>
{
public bool Success { get; private set; }
public T Value { get; private set; }
public ParseResult(T value, bool success):this()
{
Value = value;
Success = success;
}
}
class Program
{
static ParseResult<int> TryParse(string s)
{
int lret = 0;
if (int.TryParse(s, out lret))
{
return new ParseResult<int>(lret, true);
}
else
{
return new ParseResult<int>(lret, false);
}
}
static void Main(string[] args)
{
string test = "1";
var lret = TryParse(test);
if( lret.Success )
{
Console.WriteLine("{0}", lret.Value);
}
}
}
That approach is still quite efficient and spares you the out parameters at the cost of the allocation of a cheap container object.

How to create one string from list of String? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Concat all strings inside a List<string> using LINQ
I am using C# 4.0, where I have a list non-null of string objects.
IList<String> Errors
What I want to do is to create a single string which has all list elements appended, one after another, with a new line character.
public String ErrorMessage
{
get { return Errors.SomeMethodHere(); }
}
One way I could think of is to loop on list of string. Is there any better way or in built System.String or LINQ method which I can use for this?
String.Join(Environment.NewLine, Errors.ToArray());
Try String.Join(Environment.NewLine, Errors.ToArray()) (for .NET 4 and up you don't need the ToArray)
More Info: http://msdn.microsoft.com/en-us/library/57a79xd0.aspx
public String ErrorMessage
{
get
{
//Use your appropriate separator instead of ','
return string.Join(",", Errors);
//return string.Join("", Errors); // Just concatenating all message
}
}
Errors.Aggregate((left, right) => string.Format(#"{0}\n{1}", left, right));
public static class MyExtensions
{
public static string ErrorMessage(this IList<String> strList)
{
string retMessage = null;
for (int i = 0; i < strList.Count; i++)
{
retMessage += strList[i].ToString() + Environment.NewLine;
}
return retMessage;
}
}
you can use the above code snippest to make an extended method to generate single string from list data.

Categories

Resources