write changes in a csv file with c# - c#

I am trying to change a value of csv file in C# console.
First I load the content of the csv file into the code. Then I change a value and try to save it.
This is the content of the csv before (and sadly after) execution:
1;Geg;17
2;Geg;17
3;Geg;17
During runtime the values change into:
new Values
But somehow they do not get saved into the csv file.
This is my code:
main class:
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Text.RegularExpressions;
namespace csvtest
{
class Program
{
static void Main(string[] args)
{
Tabelle tab = new Tabelle();
foreach (Employees e in tab.getAll())
{
Console.WriteLine(e);
}
tab.updating(1, "fafdsdsf", 323);
}
}
}
Tabelle class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace csvtest
{
class Tabelle
{
private List<Employees>liste;
public Tabelle()
{
liste = new List<Employees>();
string[] rows = File.ReadAllLines(#"C:\Users\rbc\Desktop\csvtest\csvtest\obj\test.csv");
foreach (string row in rows)
{
string[] information = row.Split(';');
int number = int.Parse(information[0]);
string name = information[1];
double salary = double.Parse(information[2]);
liste.Add(new Employees { Number = number, Name = name, Salary = salary });
}
}
public Employees[] getAll()
{
return liste.ToArray();
}
public void adding(int number, string name, double salary)
{
liste.Add(new Employees { Number = number, Name = name, Salary = salary });
}
public void updating(int number, string name, double salary)
{
foreach (Employees e in liste)
{
if (e.Number == number)
{
e.Name = name;
e.Salary = salary;
}
}
}
~Tabelle()
{
string[] information = new string[liste.Count];
for (int i = 0; i<liste.Count; i++)
{
information[i] = liste[i].Number + ";" + liste[i].Name + ";" + liste[i].Salary;
}
File.WriteAllLines(#"C:\Users\rbc\Desktop\csvtest\csvtest\obj\test.csv", information);
}
}
}
Employees class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace csvtest
{
class Employees
{
public int Number { get; set; }
public string Name { get; set; }
public double Salary { get; set; }
public override string ToString()
{
return Number + "|" + Name + "|" + Salary;
}
}
}
I have no idea what the problem is. I appreciate any ideas or hints.
Thanks a lot in advance for your help!!

As other people suggested here, it's true that the developer hasn't control over when the finalizer is called. The garbage collector decides when to free the memory.
But, you should look at Dispose. If you implement IDisposable, and dispose of your object, then the code in Dispose will run.
First of all, your class should implement the above interface
class Tabelle : IDisposable
Then you need to wrap your code from destructor with the Dispose() method.
public void Dispose()
{
string[] information = new string[liste.Count];
for (int i = 0; i < liste.Count; i++)
{
information[i] = liste[i].Number + ";" + liste[i].Name + ";" + liste[i].Salary;
}
File.WriteAllLines(#"data.txt", information);
GC.SuppressFinalize(this);
}
Also, don't forget to use using keyword when creating your class.
using (Tabelle tab = new Tabelle())
{
foreach (Employees e in tab.getAll())
{
Console.WriteLine(e);
}
tab.updating(1, "fafdsdsf", 323);
}

Related

Breadth First Search Algorithm Does Not Work Results in Infinite Loop

I am trying to do a BFS search where I dynamically create the Nodes of the graph as I search the State Space. I followed the book but it does not work the frontier keeps on running and the explored set stays at the start value only. Please help, I have been stuck here for 4 days. Still a beginner programmer.
Problem Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
internal class Problem
{
public State start { get; set; }
public State end { get; set; }
public string[] action = { "UP", "LEFT", "DOWN", "RIGHT" };
public Problem(State x, State y)
{
start = x;
end = y;
}
public State Result(State s , string a)
{
State up;
if (a == "UP" && s.X - 1 >= 0)
{
up = new State(s.X - 1, s.Y);
}
else if (a == "LEFT" && s.Y - 1 >= 0)
{
up = new State(s.X, s.Y-1);
}
else if (a == "DOWN" && s.X + 1 < 5)
{
up = new State(s.X, s.Y+1);
}
else if( a == "RIGHT" && s.Y + 1 < 11)
{
up = new State(s.X + 1, s.Y);
}
return up;
}
public bool GoalTest(Node<State> goal)
{
if (goal.Data.Equals(end))
{
return true;
}
return false;
}
}
}
Search Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
internal class Search
{
public void BFS(Problem p)
{
Queue<Node<State>> frontier = new Queue<Node<State>>();
HashSet<string> explored = new HashSet<string>();
List<Node<State>> nNodes = new List<Node<State>>();
Node<State> root = new Node<State>() {Data = p.start,};
frontier.Enqueue(root);
while(frontier.Count > 0)
{
Node<State> next = frontier.Dequeue();
if(!explored.Add(next.Data.Data)) continue;
next.Children = new List<Node<State>>();
foreach(string action in p.action)
{
next.Children.Add(new Node<State>() { Data = p.Result(next.Data, action), Parent = next });
}
for(int i = 0; i < next.Children.Count; i++)
{
if (p.GoalTest(next.Children[i]) == true)
{
//Solution(next.Children[i]);
break;
}
frontier.Enqueue(next.Children[i]);
}
}
}
public void Solution(Node<State> n)
{
while(n.Parent != null)
{
Console.WriteLine(n.Parent.Data);
}
}
}
}
Node Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
internal class Node<T>
{
public T Data { get; set; }
public Node<T>? Parent { get; set; }
public List<Node<T>> Children { get; set; }
}
}
State Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Test
{
internal class State
{
public int X { get; set; }
public int Y { get; set; }
public string Data { get; }
public State(int x, int y)
{
X = x;
Y = y;
Data = $"{X}-{Y}";
}
}
}
Main Program
using Test;
State start = new State(0, 1);
State end = new State(3, 7);
Problem p = new Problem(start, end);
Search s = new Search();
s.BFS(p);
This is actually for my assignment hence I named it test.
I am trying to implement the pseudocode from here: (Page 82)
https://zoo.cs.yale.edu/classes/cs470/materials/aima2010.pdf
Update
It does not stuck now but it does not input anything into the console after the loop runs it is supposed to get the links between the goal node and the start node via the "Parent property".
You are never checking if nodes are already explored, so you will likely enter an infinite loop:
explored.Add(next.Data.Data);
should be
if(!explored.Add(next.Data.Data)) continue;
But there might be other problems with the code. I would highly recommend reading Eric Lipperts article How to debug small programs since problems like this should be fairly easy to find and fix yourself with the help of a debugger. Learning how to use a debugger is an invaluable skill that will make troubleshooting much easier.
I would also recommend removing all the strings from your program. Instead you should create type representing a coordinate, i.e. a Point, or vector2Int. I would recommend making this a readonly struct, and add ToString overload, IEquality<Point> implementation, operators for addition subtraction, equality etc. This type could then be used both for representing the state, and to represent the offsets. Such a type would be reusable for all kinds of different projects.

How do i convert from Task To List in this case?

I'm getting this error...
Cannot implicitly convert type 'System.Threading.Tasks.Task System.Collections.Generic.List Thoughts.ViewModel.PickerViewModel.Location'** to **'System.Collections.Generic.List Thoughts.ViewModel.PickerViewModel.Location '
Anyone an idea?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Net.Http;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Xamarin.Essentials;
namespace Thoughts.ViewModel
{
public class PickerViewModel
{
public List<Location> LocationsList { get; set; }
public class Location
{
public string name { get; set; }
}
public PickerViewModel()
{
LocationsList = GetLocations();
}
public async Task<JToken> GoogleApi()
{
var location = await Geolocation.GetLastKnownLocationAsync();
string locationString = location.Latitude.ToString() + "," + location.Longitude.ToString();
string radius = "2000";
string apiKey = "My_API_KEY";//Ofcourse its filled in
var httphelper = new HttpClient();
string link = "https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=" + locationString + "&radius=" + radius + "&key=" + apiKey;
var data = await httphelper.GetStringAsync(link);
var jsonData = JObject.Parse(data)["results"];
return jsonData;
}
public async Task<List<Location>> GetLocations()
{
JToken data = await GoogleApi();
var locationList = new List<Location>() { };
foreach (var location in data)
{
new Location() {name = location["name"].ToString() };
}
return locationList;
}
}
}
A Task<T> is a Task wrapper around a value. Normally, you would unwrap it using await.
However, in this case, the value you're unwrapping is something you want to display in a UI. So here you would want to have your constructor set up something to display in the meantime (an empty collection, or a "Loading..." indicator). Your constructor should then start an asynchronous operation that updates the data to display. This article goes into more details on this pattern.

"Not all code paths return a value" C#

Hello i am currently in the infant stages of writing a petshop app on Windows phone/C#. I have made the class below to set up my generic lists and to be able to add the pets to the shop using the given fields ( Name, age, breed and type ). The problem i believe lies in the fact that i am making a display method to be called (in another page which is below called Mainpage.xaml.cs) below called DisplayShop() and i am reading in 3 strings and an int, i believe it has something to do with the fact that my DisplayShop() method is a string, although i tried to rectify the problem by converting the age field to a string in the Display() method, although this has not fixed the problem.
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Assignment_1
{
public class Shop
{
private string name;
private int age;
private string breed;
private string type;
public Shop(string Name, int Age, string breed, string Type)
{
this.Name = name;
this.Age = age;
this.breed = breed;
this.Type = type;
}
public string Name
{
get
{
return this.name;
}
set
{
this.name = value;
}
}
public int Age
{
get
{
return this.age;
}
set
{
this.age = value;
}
}
public string Breed
{
get
{
return this.breed;
}
set
{
this.breed = value;
}
}
public string Type
{
get
{
return this.type;
}
set
{
this.type = value;
}
}
//Create the Collection
List<Shop> myShop = new List<Shop>();
public String Display()
{
return (Name + "\n" + Age.ToString() + "\n" + Breed + "\n" + Type);
}
public String DisplayShop()
{
foreach (Shop tmp in myShop)
{
tmp.Display();
}
}
}
}
Here is the Mainpage.xaml.cs page
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace Assignment_1
{
public partial class MainPage : PhoneApplicationPage
{
List<Shop> myShop = new List<Shop>();
// Constructor
public MainPage()
{
InitializeComponent();
setUpShop();
}
//Add animals to the Shop
private void setUpShop()
{
myShop.Add(new Shop("John", 3 ,"Labrador", "Dog"));
myShop.Add(new Shop("Billy", 9, "Terrier", "Dog"));
myShop.Add(new Shop("Sam", 2, "Persian", "Cat"));
myShop.Add(new Shop("Molly", 3, "Siamese", "Cat"));
myShop.Add(new Shop("Nemo", 1, "Clown Fish", "Fish"));
myShop.Add(new Shop("Dory", 1, "Palette Surgeonfish", "Fish"));
myShop.Add(new Shop("Keith", 1, "Bearded Dragon", "Lizard"));
myShop.Add(new Shop("Ozzy", 1, "Gecko", "Lizard"));
imgHolder1.Items.Add(myShop[1].DisplayShop());
}
}
}
The aim of this first part is to add the pets to an listBox in my windows app, if any of you could suggest a fix to this problem it would be much appreciated, I have included an image of the the way the phone app currently looks >>> http://gyazo.com/06217efae9265d0fef59cd2a44be7923 and the error code >>> http://gyazo.com/40c47628f1dfb7d735af4c72dde3a651
Thanks in advance,
Jason
Looks like you forgot to return value from DisplayShop funcion:
public String DisplayShop()
{
List<string> shops = new List<string>();
foreach (Shop tmp in myShop)
{
shops.Add(tmp.Display());
}
return string.Join(",", shops);
}
Join used here just to show the general idea, you can use whatever you want to construct the whole string.
You are not returning anything from this function:
public String DisplayShop()
You should return a string from it, or just change return type to void if you don't want to return anything:
public void DisplayShop()
Update:
imgHolder1.Items.Add(myShop[1].DisplayShop());
In this line you are calling DisplayShop on a Shop instance,but you didn't add any elements to the list that is inside of the Shop class.You create a seperate list.So in this case even if it works myShop[1].DisplayShop() won't display anything because your initial myShop list is empty.If you want to display one Shop just call your Display method.Anyway,probably you don't need that initial list, if you want to add all Shops to the listBox then use a simple foreach loop:
foreach(var shop in myShop)
{
imgHolder1.Items.Add(shop.Display());
}
public String DisplayShop()
{
foreach (Shop tmp in myShop)
{
tmp.Display();
}
}
your return type is a String but you aren't returning anything. Not all code paths return a value is telling you exactly that

Using a ComboBox as filter

I have made a program that is a kind of a wiki, but in a program. I've added lots of pictureBoxes, and I have 3 filters to sort those pictureBoxes: ROLE, ATTACK TYPE and NAME.
What I'd like to do is, like, if you select the Attack Type RANGED it disables the other pictureBoxes that has a different Attack Type than RANGED.
I've tried comparing each Hero (I've made a different class for it) with a timer, but I didn't know how to do it.
I also tried this
if(comboBox1.Text == "RANGED") { //do stuff }
But I don't know how could I access all of the heroes inside an array I made, and check if they have atkType = RANGED.
My Hero.cs class:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
namespace WindowsFormsApplication1
{
public struct Hero
{
public string Name;
public string Role; /* carry, disabler, lane support, initiator, jungler, support, durable, nuker, pusher, escape */
public string atkType; /* melee or ranged */
public string Type; /* strength, agility or intelligence */
public string imgName;
public Hero(string name, string role, string atktype, string type, string imgname)
{
Name = name;
Role = role;
atkType = atktype;
Type = type;
imgName = imgname;
}
public static Hero[] heroes = new Hero[] {
new Hero() {Name = "test", Role = "", atkType = "Melee", Type = "Strength", imgName = "test" }
};
}
}
I've managed to get the filter working, but now, there's only a problem: I can't dispose (images wont unload) the current loaded images and can't load new ones.
What I tried:
if (melee == false && ranged == false)
{
for (int i = 0; i < Hero.heroes.Length; i++)
{
imgs[i].Load("http://cdn.dota2.com/apps/dota2/images/heroes/" + Hero.heroes[i].imgName + "_sb.png");
comboBox3.Items.Add(Hero.heroes[i].Name);
//imgs[i].MouseHover += displayInfo(i);
}
}
if (ranged == true)
{
for (int i = 0; i < Hero.heroes.Length && Hero.heroes[i].atkType.Contains("Ranged"); i++)
{
imgs[i].Image.Dispose();
imgs[i].Load("http://cdn.dota2.com/apps/dota2/images/heroes/" + Hero.heroes[i].imgName + "_sb.png");
}
}
The code could be something like this:
if(cmb.text=="goofy")
//Code
else if(cmb.text=="mars")
//Other code
else
//BLA BLA

Which way is better Linq Select Query or For Loop to search something in generic List?

As far as performance is concerned,
Which way is better Linq Select Query or For Loop to search something in generic List?
A for loop may well be very slightly faster. Measure it to find out for sure... but then look at the readability. (EDIT: When you measure it, try doing so for rather longer than the benchmark in the accepted answer does. Also compare the time taken for this piece of code with the time for the rest of your program. Is this really a bottleneck?)
I wouldn't usually use a "select" unless you actually need to project a sequence of results though. To find a single element, either use:
list.Find(x => x.Name == "Foo");
or
list.FirstOrDefault(x => x.Name == "Foo");
I believe both of these are significantly more readable than the corresponding for loop. If you're just looking for an object then you might want to consider using a HashSet<T> instead or in combination with the list.
EDIT: Here's a benchmark to test it. Code is below results.
c:\Users\Jon\Test>test 1000000 500000 1000
FindCustomerLinq: 28531
FindCustomerListFind: 12315
FindCustomerForLoop: 9737
FindCustomerForEachLoop: 14743
So that's looking in a list of a million elements, finding one half way through it, but doing it 1000 times. So yes, the for loop is actually three times as fast... but you'd have to be doing this an awful lot before this difference actual becomes significant. If you're doing this kind of thing that much, you should look for other options such as a Dictionary.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
public class Customer
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
}
class Test
{
static void Main(string[] args)
{
int size = int.Parse(args[0]);
int id = int.Parse(args[1]);
int iterations = int.Parse(args[2]);
var list = new List<Customer>(size);
for (int i=0; i < size; i++)
{
list.Add(new Customer {
ID = i,
Address = "Address " + i,
Name = "Cusomer Name " + i,
Phone= "Phone " + i,
});
}
Time(FindCustomerLinq, list, id, iterations);
Time(FindCustomerListFind, list, id, iterations);
Time(FindCustomerForLoop, list, id, iterations);
Time(FindCustomerForEachLoop, list, id, iterations);
}
static void Time(Func<List<Customer>, int, Customer> action,
List<Customer> list,
int id, int iterations)
{
Stopwatch sw = Stopwatch.StartNew();
for (int i=0; i < iterations; i++)
{
action(list, id);
}
sw.Stop();
Console.WriteLine("{0}: {1}", action.Method.Name, (int) sw.ElapsedMilliseconds);
}
static Customer FindCustomerLinq(List<Customer> customers, int id)
{
return customers.FirstOrDefault(c => c.ID == id);
}
static Customer FindCustomerListFind(List<Customer> customers, int id)
{
return customers.Find(c => c.ID == id);
}
static Customer FindCustomerForLoop(List<Customer> customers, int id)
{
for (int i=0; i < customers.Count; i++)
{
if (customers[i].ID == id)
{
return customers[i];
}
}
return null;
}
static Customer FindCustomerForEachLoop(List<Customer> customers, int id)
{
foreach (Customer c in customers)
{
if (c.ID == id)
{
return c;
}
}
return null;
}
}
Some days before i tried same thing as R&D for 50000 Records and found that
for loop takes approx 60% time as the time taken by linq where clause
Elapsed time for Linq : 87 ms
Elapsed time for Linq : 48 ms
Elapsed time for Linq : 143 ms
Elapsed time for Linq : 76 ms
and so on.. for details please see the code how i did it
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
namespace SearchingList
{
public partial class Form1 : Form
{
private int searchingID = 0;
public int SearchingID
{
get
{
if (string.IsNullOrEmpty(txtID.Text))
searchingID = 0;
else
int.TryParse(txtID.Text, out searchingID);
return searchingID;
}
set
{
SearchingID = searchingID;
}
}
public Form1()
{
InitializeComponent();
}
private void btnsearch_Click(object sender, EventArgs e)
{
List<Customer> lstcustomersFound = new List<Customer>();
Stopwatch stp = new Stopwatch();
stp.Start();
lstcustomersFound = GetSearchedCustomersByLinq(SearchingID, (List<Customer>)dgvAllData.DataSource);
stp.Stop();
lblLinq.Text = "Elapsed Time Linq : " + stp.ElapsedMilliseconds.ToString() + " ms";
stp.Start();
lstcustomersFound = GetSearchedCustomersByForLoop(SearchingID, (List<Customer>)dgvAllData.DataSource);
stp.Stop();
lblFor.Text ="Elapsed Time for loop : " + stp.ElapsedMilliseconds.ToString() + " ms";
dgvSearched.DataSource = lstcustomersFound;
}
private List<Customer> GetSearchedCustomersByForLoop(int searchingID, List<Customer> lstcustomers)
{
List<Customer> lstcustomersFound = new List<Customer>();
foreach (Customer customer in lstcustomers)
{
if (customer.CusomerID.ToString().Contains(searchingID.ToString()))
{
lstcustomersFound.Add(customer);
}
}
return lstcustomersFound;
}
private List<Customer> GetSearchedCustomersByLinq(int searchingID, List<Customer> lstcustomers)
{
var query = from customer in lstcustomers
where customer.CusomerID.ToString().Contains(searchingID.ToString())
select customer as Customer;
return query.ToList();
}
private void Form1_Load(object sender, EventArgs e)
{
List<Customer> customers = new List<Customer>();
Customer customer;
for (int id = 1; id <= 50000; id++)
{
customer = new Customer();
customer.CusomerAddress = "Address " + id.ToString();
customer.CusomerID = id;
customer.CusomerName = "Cusomer Name " + id.ToString();
customer.CusomerPhone= "Phone " + id.ToString();
customers.Add(customer);
}
dgvAllData.DataSource = customers;
}
}
}
Customer Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SearchingList
{
public class Customer
{
public int CusomerID { get; set; }
public string CusomerName { get; set; }
public string CusomerAddress { get; set; }
public string CusomerPhone { get; set; }
}
}
As performance is consideration i will go for For Loop instead of Linq

Categories

Resources