Problems with a list and array - c#

I have been working on a program that can calculate molecularweight from a chemical formula.
So far it works pretty well, until this error occured. I want to make an array that split the chemical formula (It works fine). From here I want to make a method call, that send the array to another method. Where it is used to calculate the molecularweight from the elements in the chemical formula, and add it to a new list. Then return the list to the first method. Here's is the code (Only showing for 1 element or code gets too large);
private void Textbox1_TextChanged(object sender, EventArgs e)
{
string input = Textbox1.Text;
string pattern = #"([A-Z][a-z]?\d*|[A-Z]?\d*)";
string[] substrings = Regex.Split(input, pattern);
MoleculeweightCalculator(substrings);
Textbox2.Text = Convert.ToString(MoleculeWeightList.Sum());
}
private static MoleculeweightCalculator(string[] substrings)
{
List<double> MoleculeWeightList = new List<double>();
foreach (string match in substrings)
{
if (match == "H")
{
MoleculeWeightList.Add(1.008);
}
}
return MoleculeWeightList;
}
The problem is that it won't allow me to send the array to the other method and returning the list to the first method again. Any ideas what is wrong? Or how to solve it?

There are many mistakes in your code, return has to be lowercase and you should place it out of the loop, then the return type is missing. Moreover you aren't storing the returned data.
This should at least compile:
private void Textbox1_TextChanged(object sender, EventArgs e){
string input = Textbox1.Text;
string pattern = #"([A-Z][a-z]?\d*|[A-Z]?\d*)";
string[] substrings = Regex.Split(input, pattern);
var result = MoleculeweightCalculator(substrings);
Textbox2.Text = Convert.ToString(result.Sum());
}
private static List<double> MoleculeweightCalculator(string[] substrings){
List<double> MoleculeWeightList = new List<double>();
foreach (string match in substrings){
if (match == "H")
MoleculeWeightList.Add(1.008);
}
return MoleculeWeightList;
}

You aren't actually using the return value. The MoleculeWeightList variable is local to that function, and more specifically, to that scope and can't be used outside of it. But because you return it, you can do this:
List<double> weightList = MoleculeweightCalculator(substrings);
Textbox2.Text = Convert.ToString(weightList.Sum());
That assigns the return value to a local variable in the calling method, which you can then use later in the method.

Related

how to convert a String list into a String array then converting it into an int array then counting the total sum of the numbers in the array?

So I am so fresh into the world of programming, starting new, I decided to start messing around in C# to create simple apps from ideas that come to mind, with this little app, I'm trying to have multiple TextBoxes named d1,d2,d3,d4,etc... the user inserts numbers into the textboxes then clicks button1, which begins the process in the code below creating a new list which contains all of the values of the textboxes and then the list is converted to an array and the array is then converted into an int array, etc....
BUT, when starting the application and I add values to the textboxes and then click button1, it shows 2 error like shows in the //gray code line below
Please help.
private void button1_Click(object sender, EventArgs e)
{
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
foreach(string numb in dodo)
{
if (numb == "")
numb = "0"; //numb word has a red underline
}
string[] terms = dodo.ToArray();
int[] valv = {};
int x = 0;
for(int i=0;i<=19;i++)
{
valv[i] = int.Parse(terms[i]); //the ; in the end has a red underline and shows "FormatException was unhandled" error
i++;
x = x + valv[i];
}
string myString;
myString = x.ToString();
Result1.Text = myString;
}
you can't change the iteration variable which is numb in your case. Please change in the List container instead
List<string> dodo = new List<string>();
dodo.Add(d1.Text); dodo.Add(d2.Text); dodo.Add(d3.Text); dodo.Add(d4.Text); dodo.Add(d5.Text);
dodo.Add(d6.Text); dodo.Add(d7.Text); dodo.Add(d8.Text); dodo.Add(d9.Text); dodo.Add(d10.Text);
dodo.Add(d11.Text); dodo.Add(d12.Text); dodo.Add(d13.Text); dodo.Add(d14.Text); dodo.Add(d15.Text);
dodo.Add(d16.Text); dodo.Add(d17.Text); dodo.Add(d18.Text); dodo.Add(d19.Text); dodo.Add(d20.Text);
int k = 0;
foreach (string numb in dodo)
{
if (numb == "")
{
//numb = "0"; //numb word has a red underline
dodo[k] = "0";
}
k++;
}
Now your code on parsing into integer won't give any runtime error.
The first line "tells" you that you are not able to assign a new value to the variable which is used as a foreach iteration variable.
The second line, "tells" you that you have string value which is not able to be parsed correctly (e.g. user put string which is not a number). To avoid this you can use Int32.TryParse method instead, which will safely try to parse the given string.
The best and easiest way to achieve what you need is using LINQ methods, here is the example based on few things/assumptions:
Since you are converting empty strings into zeros, you could simply skip those entries from counting
To avoid FormatException, you should use TryParse method instead. Since TryParse method will safely parse the given string, you don't even have to filter empty strings at all (they will be skipped). However, I deliberately left filtering part, to get you a better overview of a solution.
You can use list initializer to make list initialization more readable
Solution:
List<string> dodo = new List<string>()
{
d1.Text, d2.Text //...others
};
int sum = dodo
.Where(item => !String.IsNullOrEmpty(item))
.Sum(item =>
{
if (Int32.TryParse(item, out int parsedItem))
{
return parsedItem;
}
return 0;
});
You can get more familiar with LINQ and used methods on following link

Read only assignment String c#

I'm trying to assign "tela[counter] = letra.ToString();", but it shows up the following error message "Property or indexer 'string.this[int] cannot be assigned to -- it is read only".
I saw some topics saying that you have to define {get;set;} to the atribute, but I've done this, and it didn't work.
[OBS] I tried to create get and set methods but the problem persisted
public String tela { get; set; }
private void btnSendWord_Click(object sender, EventArgs e)
{
char letra = Convert.ToChar(txtGetWord.Text);
MessageBox.Show(comboPalavra[0]);
Boolean codigoVerificador;
codigoVerificador = verificador.VerificaLetra(comboPalavra[0],letra);
if (codigoVerificador == true)
{
foreach(char c in comboPalavra[0].ToCharArray())
{
counter++;
if(c == letra)
{
tela[counter] = letra.ToString();
}
}
}
else MessageBox.Show("Nao contem");
}
Strings are immutable, meaning that you can't change a variable's value without creating a new string.
You are trying to change a single character in a string here, which is not allowed:
tela[counter] = letra.ToString();
A solution to this is to use StringBuilder. You can think of it as a mutable version of string.
You can declare a StringBuilder outside the loop:
var telaBuilder = new StringBuilder(tela);
In the loop, change the erroneous line to:
telaBuilder[counter] = letra;
And after the loop, assign telaBuilder to tela:
tela = telaBuilder.ToString();
Don't forget using System.Text!
This is the signature of the indexer for a string:
public char this[int index] { get; }
See that it returns a char and only has a get, that means it is readonly and you cannot assign something to it. This is why you are getting the error.
If you want to replace a specific letter in a string at a specific position, you can do it like this:
var name = "ferry Seinfeld";
char[] nameArray = name.ToArray();
nameArray[0] = 'J';
name = new string(nameArray);
Please look into Replace method of String and also look into StringBuilder class to see if those will suit your needs.

Find every same letters in a word

I'm working on a Hangman project that requires me to change characters "-" to "a to z". Since I'm learning how to code with C#, I have no clue how to do it.
I obviously need to use position because of the case where the word as duplicated letters (EX.: C oo kies)
Here's the code I developed, it makes my thing crashes and it's obviously incomplete.
private void chkA_Checked(object sender, RoutedEventArgs e)
{
if (motRechercher.Contains("a"))
{
int indexDemotRechercher = motRechercher.IndexOf("a");
int k = indexDemotRechercher;
var StringBuilderOP = new StringBuilder(motRechercher);
StringBuilderOP.Remove(indexDemotRechercher, indexDemotRechercher);
StringBuilderOP.Insert(k, "A");
}}
motRechercher is a STRING that I can use everywhere that I randomly pick from a list of 27 words. If this bother, it's a check-box and where I write the text is a Text-box(called txtMot).
Feel free to use other variables, I'll re-adapt after for my own comprehension. I would just like some explanation/examples to help my learning experience.
Here is the code of the randomiser if you really feel like this can help you understand[It works] :
private void btnDemarrer_Click(object sender, RoutedEventArgs e)
{
Random rdn = new Random();
int nbreAleatoire = rdn.Next(0, 27);
motRechercher = lesMots[nbreAleatoire];
if (motRechercher.Length > 0)
{
String str = new String('-', motRechercher.Length);
txtMot.Text = str;
}
}
QUESTION : How do I make a thing that detects duplicate and that will change the "-" to "a-z"?
Ask questions and I'll try to answer them if you think it's unclear.
Here is a quick sample... I have two strings... one for the hidden word the user does NOT see, and another for the one presented, using "-" or even "_" as place-holders for the actual characters.
I have a simple function "IsThereA" which expects a single letter as to the guess of a letter in the word. I then just call for all the letters including a few random ones. The function returns boolean so you can draw the hangman as each failure occurs.
In the "IsThereA" method, I am looking one character at a time for the guessed letter. If found, I replace it by using substring instead of the "-". So once updated, you can use the "WordUserCanSee" property however you need to.
This version doesn't do case-sensitive, but you can adjust as needed.
public class Hangman
{
string HangmanWord = "cookies";
string WordUserCanSee = "-------";
public Hangman()
{
IsThereA("o");
IsThereA("f");
IsThereA("k");
IsThereA("w");
IsThereA("i");
IsThereA("c");
IsThereA("s");
IsThereA("e");
}
public bool IsThereA(string guessLetter)
{
bool anyMatch = false;
for (int i = 0; i < HangmanWord.Length; i++)
{
if (HangmanWord.Substring(i, 1).Equals(guessLetter))
{
anyMatch = true;
WordUserCanSee = WordUserCanSee.Substring(0, i) + guessLetter + WordUserCanSee.Substring(i + 1);
}
}
return anyMatch;
}
}
motRechercher = motRechercher.Replace("-", "a-z");

Simple "realtime" search using listview and streamreader

I'm attempting to make a simple realtime search using a streamreader to read from a txt file and search and display the results in a listview, problem is I can only search for 1 letter, so searching for "1" will show me results for everything starting with 1, example search 1 results in "123", but searching for "12" or "123" wont show the same result. Easier explained with this code I've tried.
Edit, text-file I'm reading from has this structure:
123;asd;asd;asd;asd;asd;asd <- example of a row
public static string[] testtt(string sökord)
{
StreamReader asd = new StreamReader("film.txt");
string temp;
string[] xd;
while (asd.Peek() >= 0) // if I can read another row (I.E next row isnt empty)
{
temp = asd.ReadLine();
xd = temp.Split(';');
for (int i = 0; i < xd.Length; i++)
{
// this should check if my searchword is equal to any member of "xd"
// but this is where the problem occurs when the input is more than 1
// character, will post error message from debugger below this code.
if (xd[i].Substring(0, sökord.Length).ToLower() == sökord.ToLower())
return xd;
}
}
return null;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
try
{
listView1.Items.Clear();
ListViewItem item = new ListViewItem(testtt(textBox1.Text)[0]);
item.SubItems.Add(testtt(textBox1.Text)[1]);
item.SubItems.Add(testtt(textBox1.Text)[2]);
item.SubItems.Add(testtt(textBox1.Text)[3]);
item.SubItems.Add(testtt(textBox1.Text)[4]);
item.SubItems.Add(testtt(textBox1.Text)[5]);
item.SubItems.Add(testtt(textBox1.Text)[6]);
listView1.Items.Add(item);
if (textBox1.Text == "")
listView1.Items.Clear();
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
}
}
ex
{"Index and length must refer to a location within the string.\r\nParameter name: length"} System.Exception {System.ArgumentOutOfRangeException}
This is fairly simple. This error will always appear when the line you have read form the stream reader, and you split and store the value in xd. Say the length of xd is n. And the sokord string you entered has say m length. Now when you write:
(xd[i].Substring(0, sökord.Length)
whenever the length of xd that is n is less than m, the Substring function would be trying to make a substring of m letters from only n letters. And hence it gives the error you mentioned.
In any case just a simple check should do ok:
String sString = null;
if(xd[i].length>=sokord.length){
sString = xd[i].SubString(0,sokord.length).toLower();
if(sString.equals(sokord.toLower()))
return xd;
}
Digvijay
PS: To be honest I have written the answer from what best I could understand of what is trying to be done, so the code might be a little offtrack in one scenario. But in any case the error i have described above is 100% correct. So it would be best if you just look into that and follow the track. =)
Still dont know if I understood the question correctly, but wouldnt this be much easier to read and understand?
private String[] FindSome(String searchword)
{
foreach (String s in System.IO.File.ReadLines("myfile.txt"))
{
String[] tmp = s.Split('c');
foreach (String t in tmp)
{
if (t.StartsWith(searchword,StringComparison.CurrentCultureIgnoreCase)) return tmp;
}
}
return null;
}

Check if string contains an element from list and store it

My goal is to check if a string contains any string values from a list, store that value and wrap it in HTML-tags. I'm kind of lost here.
My List:
public List<string> AccessModifiers
{
get { return _accessModifiers ?? (_accessModifiers = new List<string>()); }
}
With the values addes in a separate method:
AccessModifiers.Add("public");
AccessModifiers.Add("private");
AccessModifiers.Add("protected");
AccessModifiers.Add("internal");
AccessModifiers.Add("protected internal");
AccessModifiers.Add("void");
Let's say i was sendind the text protected void TagListView_ItemDataBound(object sender, ListViewItemEventArgs e) to the code below, what I want is to get the keywords protected and void as matchedItems to wrap in my HTML-tags. It feels like the Find method should check if the item is found, not the whole list, but I'm a bit lost here. Here's what I got so far:
foreach (var item in AccessModifiers)
{
if (UsedItems == null) // If the session is null...
{
UsedItems = new List<string>(); // ...a new one is initiated
}
if(!UsedItems.Contains(item)) // Check if the iterated item is found in the session-list
{
bool match = AccessModifiers.Any(ArticleTextBox.Text.Contains);
string matchedItem = AccessModifiers.Find(ArticleTextBox.Text.Contains);
if (match == true)
{
string openTag = "<span class='accessModifiers'>";
string closeTag = "</span>";
string newModifier = openTag + matchedItem + closeTag;
newText = newText.Replace(matchedItem, newModifier);
UsedItems.Add(matchedItem); // Add the matchedItem (used item) to the session-list not to be iterated again
}
}
}
return newText;
I can at this point only get the keyword protected to be stored, not void. It seems like it would be more simple than what I've come up with so far.
It seems like it would be more simple than what I've come up with so far.
Quite the reverse. In particular, while the example you've given is simple, the general case isn't:
public static void thisvoidmethodisstatic()
{
Console.WriteLine("private within text");
}
Basically you'll need code which understands the structure of code rather better. Simple search and replace isn't going to cut it.
The code highlighter I use on csharpindepth.com is based on a VB highlighter written by Jared Parsons. I'll see whether I can find the original source - but if not, I'm sure there are other open source code highlighters available.
EDIT: If you really are happy with just doing a naive search and replace, then you're definitely making it more complicated than you need to.
You're iterating over all the access modifiers and also looking for all of them in the loop
I would strongly recommend getting rid of the conditional list assignment - just always assign an empty list beforehand. Aside from anything else, it avoids you having to check for nullity elsewhere.
Then you've just got:
foreach (var modifier in AccessModifiers)
{
if (ArticleTextBox.Text.Contains(modifier))
{
UsedItems.Add(modifier);
string openTag = "<span class='accessModifiers'>";
string closeTag = "</span>";
string newModifier = openTag + matchedItem + closeTag;
newText = newText.Replace(matchedItem, newModifier);
}
}

Categories

Resources