How to save user input into an array
I have two modules
MODULE director: Allows you to add and remove teachers.
MODULE Informer: Gives information about the teachers available in the school.
All this in an endless loop.
To the code: I have an initial array of teachersForDirector, consisting of 10 teachers. If the user wants to add or remove a teacher, I use the DeletingTeachers, AddingTeachers methods.
The problem is that when I select the "informer" module, the values of the teachersForDirector array are reset to the original.
Code:
public static List<string> DeletingTeachers(List<string> arrayTeachers)
{
int counter = 0;
Console.WriteLine("which teacher to remove? [index]");
for (int i = 0; i < arrayTeachers.Count; i++)
{
Console.WriteLine($"teacher with number - {counter} {arrayTeachers[i]}");
counter++;
}
int index = int.Parse(Console.ReadLine());
arrayTeachers.RemoveAt(index);
Console.Clear();
for (int i = 0; i < arrayTeachers.Count; i++)
{
Console.WriteLine($"new teachers - {arrayTeachers[i]}");
}
return arrayTeachers;
}
public static List<string> AddingTeachers(List<string> arrayTeachers)
{
Console.WriteLine("enter the name of the new teacher");
arrayTeachers.Add(Console.ReadLine());
for (int i = 0; i < arrayTeachers.Count; i++)
{
Console.WriteLine($"{arrayTeachers[i]}");
}
Console.Clear();
Console.WriteLine("teachers information:");
for (int i = 0; i < arrayTeachers.Count; i++)
{
Console.WriteLine($"{arrayTeachers[i]}");
}
return arrayTeachers;
}
static void Main(string[] args)
{
while (true)
{
List<string> teachersForDirector = new List<string> { "Матвеева Н.В", "Ивашина А.С", "Изюмов Р.Н.", "Жиделев А.С.", "Карпов М.Д", "Петрова О.А", "Таран Г.Г.", "Овчарова Д.Е.", "Андреев Д.Е.", "Долгих Н.О." };
Console.WriteLine("Choose:\ndirector - 0 \ninformer - 1"); // MAIN MENU
int DirectorZeroInformerOne = int.Parse(Console.ReadLine());
Console.Clear();
if (DirectorZeroInformerOne == 0) // changing teachers
{
{
Console.WriteLine("вы хотите удалить учителя[1] или добавить нового[2]?");
int chooseDeleteOrNew = int.Parse(Console.ReadLine());
Console.Clear();
if (chooseDeleteOrNew == 1) // removing a teacher
{
DeletingTeachers(teachersForDirector);
}
if (chooseDeleteOrNew == 2) // adding a teacher
{
AddingTeachers(teachersForDirector);
}
}
}
if (DirectorZeroInformerOne == 1)
{
Console.WriteLine("information about teachers");
for (int i = 0; i < teachersForDirector.Count; i++)
{
Console.WriteLine(teachersForDirector[i]);
}
}
}
}
How do I make sure that the changed data is saved and the informer module outputs the correct information?
Related
I'm new to C# and we need to create an array that can hold 100 scores. But it needs to also accept something smaller (txt file with numbers between 0-100). My issue is that even tho I add a txt file that has 50 scores, it will think there is another 50 'blank scores' and it will count those as 0. So when my code does the average, total, and lowest score, it will mess it up. My textbook isn't being very help with the answer.
private double Total(double[] iArray)
{
double total = 0;
total = iArray.Length;
return total;
}
//Average test score
private double Average(double[] iArray)
{
double total = 0;
double average;
for (int index = 0; index < iArray.Length; index++)
{
total += iArray[index];//look into later
}
average = (double)total / iArray.Length;
return average;
} //done
//for hightest test score
private double Highest(double[] iArray)
{
double highest = iArray[0];
for (int index = 1; index < iArray.Length; index++)
{
if (iArray[index] > highest)
{
highest = iArray[index];
}
}
return highest;
} //done
private double Lowest(double[] iArray)
{
double lowest = iArray[0];
for (int index = 1; index < iArray.Length; index++)
{
if (iArray[index] < lowest)
{
lowest = iArray[index];
}
}
return lowest;
}//done
private void addFileButton_Click(object sender, EventArgs e)
{
try
{
const int SIZE = 100; //number of test
double[] scores = new Double[SIZE]; //array of the test scores
int index = 0; //loop counter
int count = 0;
double highestScore;
double lowestScore;
double averageScore;
double totalScore;
//Asking user to open a file
StreamReader inputFile;
if (openFile.ShowDialog() == DialogResult.OK)
{
inputFile = File.OpenText(openFile.FileName);
while (!inputFile.EndOfStream && count < scores.Length)//switching index to count
{
scores[count] = int.Parse(inputFile.ReadLine());
count++;
}
inputFile.Close();
}
else
{
MessageBox.Show("Operation Canceled.");
}
//Display test scores
for (index = 0; index < count; index++)
{
scoreListBox.Items.Add(scores[index].ToString());
}
//grabbing information
highestScore = Highest(scores);
lowestScore = Lowest(scores);
averageScore = Average(scores);
totalScore = Total(scores);
//display values
highesScoreLabel.Text = highestScore.ToString();
lowestScoreLabel.Text = lowestScore.ToString();
averageTestScoreLabel.Text = averageScore.ToString();
totalTestScoresLabel.Text = totalScore.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
You might just have to use Array.Resize then:
while (!inputFile.EndOfStream && scores.Count <= SIZE)
{
scores[count] = int.Parse(inputFile.ReadLine());
count++;
}
Array.Resize(scores, --count);
See if that works.
This was suggested before the OP's comment clarifying the should specifically use an array:
What if you used a List<double> when collecting the scores, then .ToArray() before you pass it into your other methods?
const int SIZE = 100;
List<double> scores = new List<double>();
[...]
if (openFile.ShowDialog() == DialogResult.OK)
{
inputFile = File.OpenText(openFile.FileName);
while (!inputFile.EndOfStream && scores.Count <= SIZE)
{
scores.Add(int.Parse(inputFile.ReadLine()));
count++;
}
[...]
var arrScores = scores.ToArray();
//grabbing information
highestScore = Highest(arrScores);
lowestScore = Lowest(arrScores);
averageScore = Average(arrScores);
totalScore = Total(arrScores);
Notice that the while loop has the condition changed for scores.Count <= SIZE to still only allow up to 100 scores.
Instead of constructing the Array yourself and implementing all these methods, I suggest, you read up in LINQ. LINQ stands for Language INtegrated Query and is essentially a bunch of extension methods on IEnumerable<T> that provide all of the functionality you need here.
I rewrote your event handler to use LINQ and it became much simpler.
private void addFileButton_Click(object sender, EventArgs e)
{
try
{
// Easier to follow if we just exit early
if (openFile.ShowDialog() != DialogResult.OK)
{
MessageBox.Show("Operation Canceled.");
return;
}
var scores = File.ReadAllLines(openFile.FileName)
// Always use TryParse to avoid exceptions
.Select(l => int.TryParse(l, out var score) ? score : -1)
// Filter out everything that is no valid score
.Where(s => s >= 0)
// You could also use ToList() here for a possible minimal performance gain and the possibility to add items later.
.ToArray();
// Display test scores
// We are using foreach instead of for here because we do not care about indexes. We simply want to add each item.
// We also do not need to add the ToString(), just adding an int is fine.
foreach (var score in scores)
scoreListBox.Items.Add(score);
// grabbing information
// We use LINQ methods here. Microsoft was nice enough di implement a bunch of often used methods on collections for us.
var highestScore = scores.Max();
var lowestScore = scores.Min();
var averageScore = scores.Average();
var totalScore = scores.Sum();
//display values
highesScoreLabel.Text = highestScore.ToString();
lowestScoreLabel.Text = lowestScore.ToString();
averageTestScoreLabel.Text = averageScore.ToString();
totalTestScoresLabel.Text = totalScore.ToString();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I want to create a minigame which select random buttons from an array of game objects and store the value in an array. After the first step is completed the user need to tap on the same buttons or he will lose. The problem is when I want to compare the values from this two arrays, every value from index 0-2 is set to 0 in both arrays. I tried to debug the adding part and that works fine, even in my editor I can see the stored values. Here is a photo:
storedobjectsEditor. I even put two for loops to check the values from array in the game, instead of getting 3 prints I get 6 of them, first 3 represent the values right and the other 3 have value = 0 (this apply to both arrays). In my CheckWin() the result will be always true because the values which are compared there are 0 for every position from both arrays. I can't figure it out what force the arrays to have all components set to zero in that method. Here is the script:
public class Script : MonoBehaviour
{
[SerializeField] private GameObject[] buttons;
[SerializeField] private int[] culoriINT;
[SerializeField] private int[] culoriComparareINT;
int index = 0;
int index2 = 0;
private bool win = false;
private void Start()
{
StartCoroutine(ChangeColors2());
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.P))
{
for (int i = 0; i < culoriINT.Length; i++)
{
Debug.Log("INT vector[" + i + "]: " + culoriINT[i]);
}
}
if (Input.GetKeyDown(KeyCode.W))
{
for (int i = 0; i < culoriComparareINT.Length; i++)
{
Debug.Log("Al doilea vector[" + i + "]: " + culoriComparareINT[i]);
}
}
}
IEnumerator ChangeColors2()
{
yield return new WaitForSeconds(1f);
for (int j = 0; j < buttons.Length; j++)
{
var randomBtn = UnityEngine.Random.Range(0, buttons.Length);
buttons[randomBtn].GetComponent<Image>().color = Color.green;
var introducereIndex = buttons[randomBtn].GetComponent<IndexButtons>().index;
culoriINT[index] = introducereIndex;
Debug.Log($"Index adaugat {introducereIndex} total {culoriINT.Length}");
index++;
yield return new WaitForSeconds(0.5f); //seteaza coloare alb pe acelas buton in cazu in care nimereste acelas sa se vada
buttons[randomBtn].GetComponent<Image>().color = Color.white;
Debug.Log("verde");
yield return new WaitForSeconds(1f);
}
}
public void OnButtonClick()
{
index2++;
}
public void numePeClick()
{
if (index2 < buttons.Length)
{
string a = EventSystem.current.currentSelectedGameObject.name;
culoriComparareINT[index2] = Convert.ToInt32(a);
Debug.Log($"Index adaugat {Convert.ToInt32(a)} total {culoriComparareINT.Length}");
}
else
{
Debug.Log("Array plin");
}
}
public void CheckWin()
{
win = true;
for (var i = 0; i < culoriINT.Length; i++)
{
if (culoriINT[i] != culoriComparareINT[i])
{
win = false;
break;
}
else
{
win = true;
}
}
if (win)
{
Debug.Log("Ai castigat!");
}
else
{
Debug.Log("Ai pierdut!");
}
}
}
It sounds like you have two instances of the same Script component in your scene. One of them has the correct values 3,2,3, the other one has the wrong values 0,0,0. This is why six values get printed to the console instead of three with a single input.
using System;
using System.Linq;
namespace CodeforWar
{
class program
{
static void Main(string[] args)
{
Path();
const int rows = 4;
const int cols = 13;
int[,] deck = new int[rows, cols];
DeckCard(deck);
DisplayDeck(deck);
Console.WriteLine();
ShuffleDeck(deck);
DisplayDeck(deck);
Console.ReadKey();
}
public static void BegMenu()
{
Console.Clear();
System.Console.WriteLine("Welcome!");
Console.WriteLine("1: Play War");
System.Console.WriteLine("2: Play Lazer");
System.Console.WriteLine("3: See Scoreboard");
System.Console.WriteLine("4: Exit Game");
}
static void Path()
{
BegMenu();
string userInput = Console.ReadLine();
while(userInput != "4")
{
if(userInput == "1")
{
War();
}
if(userInput == "2")
{
Lazers();
}
Console.Clear();
}
}
static void War()
{
Console.ReadLine();
System.Console.WriteLine("Welcome to War");
Console.WriteLine("Press a key to enter the game");
Console.ReadKey();
}
public void DisplayDeck()
{
DisplayDeck();
}
static void Lazers()
{
Console.ReadLine();
System.Console.WriteLine("Welcome to Lazers!");
Console.WriteLine("Press a key to enter the game");
Console.ReadKey();
}
static void DeckCard(int[,] arr)
{
for(int row = 0; row < 4; ++row)
for(int col = 0; col
< 13; ++col)
arr[row,
col] = 0;
}
static void DisplayDeck(int[,] arr)
{
for(int row = 0; row < 4; ++row)
{
for(int col = 0; col < 13; ++col)
Console.Write(arr[row, col] + " ");
Console.WriteLine();
}
}
static void ShuffleDeck(int [,] arr)
{
int row, col;
for (int card = 1; card <= 52; ++card)
{
Random rand = new Random();
row = rand.Next(4);
col = rand.Next(13);
if (arr[row, col] == 0)
arr[row, col] = card;
else
{
while (arr[row, col] != 0)
{
row = rand.Next(4);
col = rand.Next(13);
}
arr[row, col] = card;
}
}
}
}
}
I am trying to figure out how to give the user a card and then give them the option to guess high or lower. I haven't tried making a card deck before and I'm wondering with the current set up I have right now that it could work.
One important thing you need to consider is what happens to the card once it's been drawn from the deck? The current implementation, a two-dimensional array, looks like it will always contain all 52 cards in the deck, even after a number of cards have been drawn, because there's no mechanism for indicating that a particular card is no longer in the deck once it's been drawn. This is a bit like inserting the card back into the deck at a random position once it's been drawn and used.
Instead you might want to look at a generic type such as Queue. This will allow you to Dequeue a card from the top of the deck, and then it's no longer in the deck. At an appropriate point in the game you can put cards back onto the bottom of the deck by Queueing them.
Also, I'd suggest that the structure of your deck of cards doesn't really need to reflect the fact that a deck of cards typically consists of 4 suits with 13 cards each, you only need to take that fact into account when initialising the deck, for example:
var deck = new Queue<Card>();
foreach (var suit in possibleSuits) // heart, diamond, spade, club
{
foreach (var val in possibleValues) // ace, 2-10, jack, queen, king
{
deck.Enqueue(new Card(suit, val));
}
}
Going a bit further, you need a way of shuffling the deck, which Queue<T> doesn't give you, so at this point you might consider implementing your own Deck class, such as:
public class Deck
{
private Queue<Card> cards = new Queue<Card>();
public Deck()
{
// fill the queue as per previous snippet
}
public Card Draw()
{
return cards.Dequeue();
}
public void ReturnToDeck(Card card)
{
cards.Enqueue(card);
}
public void Shuffle()
{
// I'll let you think about how to do this ;-)
}
}
enter image description hereI'm trying to make a program that shows the prime numbers of the numbers added to the listbox from the textbox and then written in the listbox, with a message box, can anyone help me, where am I wrong?
private void button2_Click(object sender, EventArgs e)
int deneme = 0;
int sayilarim = Convert.ToInt32(textBox1.Text);
for (int i = 2; i < sayilarim; i++) {
if (sayilarim % i == 0)
deneme++;
}
if (deneme != 0){
listBox1.Items.Add(textBox1.Text + " Asal Sayi değildir.");
MessageBox.Show("Bu Bir Asal Sayi Değildir.");
} else {
listBox1.Items.Add(textBox1.Text + " sayidir.");
MessageBox.Show("Bu Bir Asal Sayi.");
}
textBox1.Clear();
}
MessageBox.Show(listBox1.Items.Count.ToString() + " Adet asal sayı var.");
First of all, your button2 is not getting value of Listbox1 ,
it takes value of textbox.
you have to take items of Listbox1 and put them in a list or etc.
and make your algorithm for them.
here is some sample code.
öncelikle buton 2 nin altında sayıları listbox içinden değil textbox'tan almışsın, onu düzeltmen gerek. listenin elemanlarında dönüp int bir listeye atama yapabilirsin. Bu adımları düzenledikten sonra altta verdiğim örnek kodu bir dene bakalım,
StringBuilder str = new StringBuilder();
str.AppendLine("Asal Olan Sayilar:");
List<int> lst = new List<int>(); // { 3, 4, 5, 10 };
for (int i = 0; i < ListBox1.Items.Count; i++)
{
lst.Add(Convert.ToInt32(ListBox1.Items[i].ToString()));
}
bool asalMi = true;
foreach (int value in lst)
{
asalMi = true;
for (int i = 2; i < value; i++)
{
if (value % i == 0)
{
asalMi = false;
}
}
if (asalMi)
str.AppendLine($"{value.ToString()} asaldir.");
}
MessageBox.Show(str.ToString);
Here is the code:
class Program
{
static void Main(string[] args)
{
List<Item> cont1 = new List<Item>();
cont1.Add(objA); //objA is local varible that has been defined.
cont1.Add(objB); //objB is local varible that has been defined.
cont1.Add(objC); //objC is local varible that has been defined.
cont1.Add(objD); //objD is local varible that has been defined.
cont1.Add(objE); //objE is local varible that has been defined.
int count = cont1.Count;
List<Item> cont2 = GroupingA(cont1, count);
for (int i = 0; i < cont1.Count; i++)
{
Console.Write(cont1[i].Name + " ");//output the item's name.
}
Console.WriteLine();
Console.Write("Container 2: ");
for (int i = 0; i < cont2.Count; i++)
{
Console.Write(cont2[i].Name + " ");//output the item's name.
}
}
}
public class GroupItem
{
public List<Item> GroupingA (List<Item> obj, int count)
{
List<Item> temp = new List<Item>();
for (int i = 0; i < count; i++)
{
if (i == count - 1)
{
break;
}
else if (temp.Count > 0 )
{
break;
}
else
{
for (int j = i + 1; j < count; j++)
{
bool equal = obj[i].EqualFirstPhase(obj[j]);
if (equal == true)
{
if (temp.Exists(element => element == temp[j]))
{
continue;
}
else
{
temp.Add(obj[j]);
if (temp.Exists(element => element == obj[i]))
{
continue;
}
else
{
temp.Insert(0, obj[i]);
}
i--;
}
}
}
}
for (int k = 0; k < count; k++)
{
for (int l = 0; l < temp.Count; l++)
{
if (obj[k].Name.Contains(temp[l].Name))
{
obj.RemoveAt(k);
count--;
}
}
if (obj.Count < count)
{
k = 0;
}
}
}
return temp;
}
}
I want to use GroupingA method to regroup the cont1 into cont2. However, there is an error.
The name 'GroupingA ' does not exist in the current context.
Anyone can help me??? Really weak in OOP, especially naming.
YOu need to use :-
GroupItem grpItem = new GroupItem();
List<Item> cont2 = grpItem.GroupingA(cont1, count);
Reason:-
Your GroupingA method is non-static and defined in the class GroupingItem. And you are trying to access it from your Program class as if the method GroupingA is a part of that class. For accessing non-static methods from other classes you need to Instantiate that class and use that object to get access to the class. In case of static method you can directly access them with the . operator on that particular class. ex Class.Method(...)
The line
List<Item> cont2 = GroupingA(cont1, count); is being called in the class Program.
Without a class name or object identifier that says where a method is located, it will look in the current class, which in your case is Program.
You have several choices.
Make the GroupingA method static and replace the line with List<Item> cont2 = GroupItem.GroupingA(cont1, count);
Make an instance of GroupItem and refer to that instead:
GroupItem g = new GroupItem();
List<Item> cont2 = your.GroupingA(cont1, count);
Move the method GroupingA out of the GroupItem class and place it within the Program class so your line knows where to find it.