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 7 years ago.
Improve this question
string db;
ComboBox fieldBox = new ComboBox()
TextBox ValueBox = new TextBox()
ListBox dbValues = new ListBox()
private void LoadDB()
{
//Structure
string myStruct = "NAME\nAGE\nSEX\nSKILL
db = "John\t20\tMale\tNoob\n
Joe\t20\tMale\tMedium\n
Jessica\t27\tFemale\tExpert\n
John\t21\tMale\tMedium
";
//Load struct to combobox
string[] mbstr = myStruct.Split('\n');
for (int i = 0; i < mbstr.Length; i++)
{
fieldBox.Items.Add(mbstr[i]);
}
string[] db2 = db.Split('\n');
for (int i = 1; i < db2.Length - 1; i++)
{
//Display name and age in combobox
dbValues.Items.Add(db2[i].Split('\t')[0] + " - " + db2[i].Split('\t')[1]);
}
}
void ValueBoxKeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode != Keys.Enter)
return;
db.Split('\n')[dbValues.SelectedIndex].Split('\t')[fieldBox.SelectedIndex] = valueBox.Text;
MessageBox.Show("Value set: " +
db.Split('\n')[dbValues.SelectedIndex + 1].Split('\t')[fieldBox.SelectedIndex]
+ " to " + valueBox.Text + ".");
}
This is where it fails:
db.Split('\n')[dbValues.SelectedIndex].Split('\t')[fieldBox.SelectedIndex] = valueBox.Text;
I tried this, and tried to assign to db, but not working though. My original string is unchanged.
I do not want to convert to list and string back, i want to change directly.
How can i do this?
Your first problem is your string: unless you use # escaping you can't have your string cross multiple lines, and if you use # escaping you can't do \t or \n and retain their escaped meaning of tab and newline.
The second problem is a fundamental misunderstanding of the .NET string, string's are immutable. Split will create an array, there is no reference back to the original string, or the second array your splitting. You would need to do something like:
[TestClass]
public class StringTest
{
public TestContext TestContext { get; set; }
[TestMethod]
public void RewriteString()
{
var str = "Garry\t19\tMale\tNoob\n" +
"Joe\t25\tMale\tMedium\n" +
"Gary\t33\tFemale\tExpert";
var rows = str.Split('\n');
var columns = rows[0].Split('\t');
columns[0] = "Jerry";
rows[0] = string.Join("\t", columns);
str = string.Join("\n", rows);
TestContext.WriteLine(str);
}
}
Test Name: RewriteString
Test Outcome: Passed
Result StandardOutput: TestContext Messages:
Jerry 19 Male Noob
Joe 25 Male Medium
Gary 33 Female Expert
Would really hope there would be an easier way to do this, possibly with a Regex?
Now to really look at your (new) question. I have refactored exactly what you have, as I do not know your data situation I'm not entirely sure using a string as a database is a good idea: (this will compile without any references because of the use of dynamic).
public class SomeView
{
string db;
dynamic fieldBox = null;
dynamic valueBox = null;
dynamic dbValues = null;
dynamic MessageBox = null;
private void LoadDB()
{
//Structure
string myStruct = "NAME\nAGE\nSEX\nSKILL";
db = "John\t20\tMale\tNoob\n" +
"Joe\t20\tMale\tMedium\n" +
"Jessica\t27\tFemale\tExpert\n" +
"John\t21\tMale\tMedium";
//Load struct to combobox
string[] mbstr = myStruct.Split('\n');
for (int i = 0; i < mbstr.Length; i++)
{
fieldBox.Items.Add(mbstr[i]);
}
string[] db2 = db .Split('\n');
for (int i = 1; i < db2.Length - 1; i++)
{
var data = db2[i].Split('\t'); //expensive only do once
//Display name and age in combobox
dbValues.Items.Add(data[0] + " - " + data[1]);
}
}
protected string Transform(string value, int row, int column, string replacement, out string old)
{
var rows = value.Split('\n');
var columns = rows[row].Split('\t');
old = columns[column];
columns[column] = replacement;
rows[row] = string.Join("\t", columns);
return string.Join("\n", rows);
}
void ValueBoxKeyDown(object sender, dynamic e)
{
if (e.KeyCode != "enter")
return;
string old;
string newValue = this.Transform(db, dbValues.SelectedIndex, fieldBox.SelectedIndex, valueBox.Text, out old);
MessageBox.Show("Value set: " + old + " to " + valueBox.Text + ".");
}
}
So this is better:
public class SomeView
{
dynamic fieldBox = null;
dynamic valueBox = null;
dynamic dbValues = null;
dynamic MessageBox = null;
private List<Person> People = new List<Person>();
private void LoadDB()
{
//Structure
string myStruct = "NAME\nAGE\nSEX\nSKILL";
string db = "John\t20\tMale\tNoob\n" +
"Joe\t20\tMale\tMedium\n" +
"Jessica\t27\tFemale\tExpert\n" +
"John\t21\tMale\tMedium";
//Load struct to combobox
string[] mbstr = myStruct.Split('\n');
for (int i = 0; i < mbstr.Length; i++)
{
fieldBox.Items.Add(mbstr[i]);
}
People.Clear();
foreach(var row in db.Split('\n'))
{
var columns = row.Split('\t');
Person p = new Person();
p.Name = columns[0];
p.Age = int.Parse(columns[1]);
p.Sex = (Person.Sexs)Enum.Parse(typeof(Person.Sexs), columns[2]);
p.SkillLevel = (Person.SkillLevels)Enum.Parse(typeof(Person.SkillLevels), columns[2]);
People.Add(p);
dbValues.Items.Add(string.Format("{0}-{1}", p.Name, p.Age);
}
}
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public enum Sexs
{
Male,
Female
}
public Sexs Sex { get; set; }
public enum SkillLevels
{
Noob,
Medium,
Expert
}
public SkillLevels SkillLevel { get; set; }
}
void ValueBoxKeyDown(object sender, dynamic e)
{
if (e.KeyCode != "enter")
return;
Person p = this.People[dbValues.SelectedIndex];
switch((int)fieldBox.SelectedIndex)
{
case 0: p.Name = valueBox.Text; break;
case 1: p.Age = int.Parse(valueBox.Text); break;
case 2: p.Sex = (Person.Sexs)Enum.Parse(typeof(Person.Sexs), valueBox.Text); break;
case 3: p.SkillLevel = (Person.SkillLevels)Enum.Parse(typeof(Person.SkillLevels), valueBox.Text); break;
default: throw new NotImplementedException();
}
MessageBox.Show("Value set: " + old + " to " + valueBox.Text + ".");
}
}
However this is still garbage, since if you have a strongly typed data set you can actually bind this to form controls without directly manipulating the item.
https://msdn.microsoft.com/en-us/library/c8aebh9k(v=vs.110).aspx
You cannot change the return-value of a method returning a string as strings are immutable. What you can do instead is the following:
string myDatabase =
"Garry\t19\tMale\tNoob\n" +
"Joe\t25\tMale\tMedium\n" +
"Gary\t33\tFemale\tExpert";
var tmp = "";
foreach(var line in myString.Split('\n')) {
tmp = tmp + Regex.Replace(line, "^.*?(?=\\t)", myReplaceText);
}
myString = tmp;
This regex will search for everything before the very first tab within every line, replaces it by "Jerry"and and concatenates every so replaced line into myString.
Related
I would like to write C# code that parses nested parenthesis to array elements, but only on first level. An example is needed for sure:
I want this string:
"(example (to (parsing nested paren) but) (first lvl only))"
tp be parsed into:
["example", "(to (parsing nested paren) but)", "(first lvl only)"]
I was thinking about using regex but can't figure out how to properly use them without implementing this behaviour from scratch.
In the case of malformed inputs I would like to return an empty array, or an array ["error"]
I developed a parser for your example. I also checked some other examples which you can see in the code.
using System;
using System.Collections;
using System.Collections.Generic;
public class Program
{
public static void Main()
{
string str = "(example (to (parsing nested paren) but) (first lvl only))"; // => [example , (to (parsing nested paren) but) , (first lvl only)]
//string str = "(first)(second)(third)"; // => [first , second , third]
//string str = "(first(second)third)"; // => [first , (second) , third]
//string str = "(first(second)(third)fourth)"; // => [first , (second) , (third) , fourth]
//string str = "(first((second)(third))fourth)"; // => [first , ((second)(third)) , fourth]
//string str = "just Text"; // => [ERROR]
//string str = "start with Text (first , second)"; // => [ERROR]
//string str = "(first , second) end with text"; // => [ERROR]
//string str = ""; // => [ERROR]
//string str = "("; // => [ERROR]
//string str = "(first()(second)(third))fourth)"; // => [ERROR]
//string str = "(((extra close pareanthese))))"; // => [ERROR]
var res = Parser.parse(str);
showRes(res);
}
static void showRes(ArrayList res)
{
var strings = res.ToArray();
var theString = string.Join(" , ", strings);
Console.WriteLine("[" + theString + "]");
}
}
public class Parser
{
static Dictionary<TokenType, TokenType> getRules()
{
var rules = new Dictionary<TokenType, TokenType>();
rules.Add(TokenType.OPEN_PARENTHESE, TokenType.START | TokenType.OPEN_PARENTHESE | TokenType.CLOSE_PARENTHESE | TokenType.SIMPLE_TEXT);
rules.Add(TokenType.CLOSE_PARENTHESE, TokenType.SIMPLE_TEXT | TokenType.CLOSE_PARENTHESE);
rules.Add(TokenType.SIMPLE_TEXT, TokenType.SIMPLE_TEXT | TokenType.CLOSE_PARENTHESE | TokenType.OPEN_PARENTHESE);
rules.Add(TokenType.END, TokenType.CLOSE_PARENTHESE);
return rules;
}
static bool isValid(Token prev, Token cur)
{
var rules = Parser.getRules();
return rules.ContainsKey(cur.type) && ((prev.type & rules[cur.type]) == prev.type);
}
public static ArrayList parse(string sourceText)
{
ArrayList result = new ArrayList();
int openParenthesesCount = 0;
Lexer lexer = new Lexer(sourceText);
Token prevToken = lexer.getStartToken();
Token currentToken = lexer.readNextToken();
string tmpText = "";
while (currentToken.type != TokenType.END)
{
if (currentToken.type == TokenType.OPEN_PARENTHESE)
{
openParenthesesCount++;
if (openParenthesesCount > 1)
{
tmpText += currentToken.token;
}
}
else if (currentToken.type == TokenType.CLOSE_PARENTHESE)
{
openParenthesesCount--;
if (openParenthesesCount < 0)
{
return Parser.Error();
}
if (openParenthesesCount > 0)
{
tmpText += currentToken.token;
}
}
else if (currentToken.type == TokenType.SIMPLE_TEXT)
{
tmpText += currentToken.token;
}
if (!Parser.isValid(prevToken, currentToken))
{
return Parser.Error();
}
if (openParenthesesCount == 1 && tmpText.Trim() != "")
{
result.Add(tmpText);
tmpText = "";
}
prevToken = currentToken;
currentToken = lexer.readNextToken();
}
if (openParenthesesCount != 0)
{
return Parser.Error();
}
if (!Parser.isValid(prevToken, currentToken))
{
return Parser.Error();
}
if (tmpText.Trim() != "")
{
result.Add(tmpText);
}
return result;
}
static ArrayList Error()
{
var er = new ArrayList();
er.Add("ERROR");
return er;
}
}
class Lexer
{
string _txt;
int _index;
public Lexer(string text)
{
this._index = 0;
this._txt = text;
}
public Token getStartToken()
{
return new Token(-1, TokenType.START, "");
}
public Token readNextToken()
{
if (this._index >= this._txt.Length)
{
return new Token(-1, TokenType.END, "");
}
Token t = null;
string txt = "";
if (this._txt[this._index] == '(')
{
txt = "(";
t = new Token(this._index, TokenType.OPEN_PARENTHESE, txt);
}
else if (this._txt[this._index] == ')')
{
txt = ")";
t = new Token(this._index, TokenType.CLOSE_PARENTHESE, txt);
}
else
{
txt = this._readText();
t = new Token(this._index, TokenType.SIMPLE_TEXT, txt);
}
this._index += txt.Length;
return t;
}
private string _readText()
{
string txt = "";
int i = this._index;
while (i < this._txt.Length && this._txt[i] != '(' && this._txt[i] != ')')
{
txt = txt + this._txt[i];
i++;
}
return txt;
}
}
class Token
{
public int position
{
get;
private set;
}
public TokenType type
{
get;
private set;
}
public string token
{
get;
private set;
}
public Token(int position, TokenType type, string token)
{
this.position = position;
this.type = type;
this.token = token;
}
}
[Flags]
enum TokenType
{
START = 1,
OPEN_PARENTHESE = 2,
SIMPLE_TEXT = 4,
CLOSE_PARENTHESE = 8,
END = 16
}
well, regex will do the job:
var text = #"(example (to (parsing nested paren) but) (first lvl only))";
var pattern = #"\(([\w\s]+) (\([\w\s]+ \([\w\s]+\) [\w\s]+\)) (\([\w\s]+\))\)*";
try
{
Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
Match m = r.Match(text);
string group_1 = m.Groups[1].Value; //example
string group_2 = m.Groups[2].Value; //(to (parsing nested paren) but)
string group_3 = m.Groups[3].Value; //(first lvl only)
return new string[]{group_1,group_2,group_3};
}
catch(Exception ex){
return new string[]{"error"};
}
hopefully this helps, tested here in dotnetfiddle
Edit:
this might get you started into building the right expression according to whatever patterns you are falling into and maybe build a recursive function to parse the rest into the desired output :)
RegEx is not recursive. You either count bracket level, or recurse.
An non-recursive parser loop I tested for the example you show is..
string SplitFirstLevel(string s)
{
List<string> result = new List<string>();
int p = 0, level = 0;
for (int i = 0; i < s.Length; i++)
{
if (s[i] == '(')
{
level++;
if (level == 1) p = i + 1;
if (level == 2)
{
result.Add('"' + s.Substring(p, i - p) + '"');
p = i;
}
}
if (s[i] == ')')
if (--level == 0)
result.Add('"' + s.Substring(p, i - p) + '"');
}
return "[" + String.Join(",", result) + "]";
}
Note: after some more testing, I see your specification is unclear. How to delimit orphaned level 1 terms, that is terms without bracketing ?
For example, my parser translates
(example (to (parsing nested paren) but) (first lvl only))
to:
["example ","(to (parsing nested paren) but) ","(first lvl only)"]
and
(example (to (parsing nested paren)) but (first lvl only))
to:
["example ","(to (parsing nested paren)) but ","(first lvl only)"]
In either case, "example" gets a separate term, while "but" is grouped with the first term. In the first example this is logical, it is in the bracketing, but it may be unwanted behaviour in the second case, where "but" should be separated, like "example", which also has no bracketing (?)
I'm just learning Windows Forms with C# and I'm having a lot of trouble rewriting my Console app into a window forms app. Here is my code in the Console App:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
const string FILENAME = #"C:\Users\annage\Desktop\SCHOOL\POS409\data.txt"; //path for CSV file
List<List<string>> EmployeesInfo = new List<List<string>>();
string inputLine = "";
StreamReader reader = new StreamReader(FILENAME);
int whileLoopRan = 0;
while ((inputLine = reader.ReadLine()) != null) //enters items into array
{
if (whileLoopRan == 0)
{
whileLoopRan++;
continue;
}
whileLoopRan = 1;
List<string> inputArray = inputLine.Split(new char[] { ',' }).ToList();//remove extra spaces
inputArray = inputArray.Select(x => x.Trim()).ToList();
EmployeesInfo.Add(inputArray);
}
List<EmployeeTaxes> EmployeeList = new List<EmployeeTaxes>();
foreach (List<string> EmployeeInfo in EmployeesInfo)
{
String employeeType;
employeeType = EmployeeInfo[5];
EmployeeTaxes employeeTaxType = new EmployeeTaxes();
employeeTaxType.GrossPay = double.Parse(EmployeeInfo[3]);
if (employeeType == ("W2"))
{
double taxes;
taxes = .07;
employeeTaxType.taxes = double.Parse(EmployeeInfo[3]) * .07;
employeeTaxType.totaltaxes = employeeTaxType.taxes * 12;
}
else if (employeeType == ("1099"))
{
}
EmployeeList.Add(employeeTaxType);
}
DisplayData(EmployeeList, EmployeesInfo);
Console.ReadLine();
}
private void DisplayData(List<EmployeeTaxes> employeeList, List<List<string>> employeesInfo)
{
for (int i = 0; i < employeeList.Count; i++)
{
List<string> Row = employeesInfo[i];
string fullName = Row[0];
string address = Row[1];
string employeeType = Row[5];
string developerType = Row[6];
EmployeeTaxes taxRow = employeeList[i];
double grossPay = taxRow.GrossPay;
double taxes = taxRow.taxes;
double totalGrossPay = taxRow.TotalGrossPay();
double annualTaxes = taxRow.totaltaxes;
double netPay = taxRow.Netpay();
Console.WriteLine("Welcome, !", fullName); // shows greeting and users name
Console.WriteLine("Address: ", address); //shows address entered
Console.WriteLine("Gross Pay: $", grossPay); // Shows gross pay entered
Console.WriteLine("Employee Type: ", employeeType);
Console.WriteLine("Monthly taxes are 7%"); ("Monthly Taxes Paid are: $" + taxes.ToString("N2")); // calculated the taxes paid monthly
Console.WriteLine("Annual Gross Pay: $" + totalGrossPay.ToString("N2")); // calulates gross pay * 12months
Console.WriteLine("Annual Taxes Paid: $" + annualTaxes.ToString("N2")); // calulates taxes * 12months
Console.WriteLine("NetPay: $" + netPay.ToString("N2"));
Console.WriteLine("Developer Type: ", developerType);
}
}
}
I am reading from a CSV .txt file and then I add it to a list of strings and I search for the "employee type" and then based on that value I loop it to do a calculation and then print out all the values.
I was able to read the csv file into a textbox in windows form, but I cannot figure out how to loop it and read the specific value and then continue with my calculation.
here is what I have for my console windows form:
public Form1()
{
InitializeComponent();
this.listBox3.SelectionMode = SelectionMode.MultiSimple;
ReadingCSVFile();
}
public void ReadingCSVFile()
{
List<List<string>> EmployeesInfo = new List<List<string>>();
string inputLine = "";
using (StreamReader sr = new StreamReader(#"C:\Users\annage\Desktop\SCHOOL\POS409\data.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
listBox3.Items.Add(line);
List<string> inputArray = inputLine.Split(new char[] { ',' }).ToList();
inputArray = inputArray.Select(x => x.Trim()).ToList();
EmployeesInfo.Add(inputArray);
}
}
private void DisplayData(List<EmployeeTaxes> employeeList, List<List<string>> EmployeesInfo)
{
for (int i = 0; i < employeeList.Count; i++)
{
List<string> Row = EmployeesInfo[i];
string fullName = Row[0];
string address = Row[1];
string employeeType = Row[5];
string developerType = Row[6];
EmployeeTaxes taxRow = employeeList[i];
double grossPay = taxRow.GrossPay;
double taxes = taxRow.taxes;
double totalGrossPay = taxRow.TotalGrossPay();
double annualTaxes = taxRow.totaltaxes;
double netPay = taxRow.Netpay();
}
}
Where can I add my loop? I tried using as much of my code in both formats, but I know console.writeline needs to be changed for windows form, but I haven't gotten that far yet.
Any assistance would be very much appreciated.
First of all it is easier to use Lambda Expressions.
So your code would look like this:
public void Test()
{
List<string> myList = new List<string>();
using (var reader = new StreamReader(#"2018-03-16.csv"))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
foreach (string item in values)
{
myList.Add(item);
}
}
}
this.FindItem(myList);
}
private void FindItem(List<string> myList)
{
// if you want the value
var match = myList.FirstOrDefault(stringToCheck => stringToCheck.Equals("your item to check"));
// if you just want to check if it exists
var match2 = myList.Any(stringToCheck => stringToCheck.Equals("your item to check"));
}
I need to check whether all parts of a string like
A=1&AW=43&KO=96&R=7&WW=15&ZJ=80
are in a big string like:
A=1&AG=77&AW=43&.....&KF=11&KO=96&.....&QW=55&R=7&....&WV=1&WW=15&....ZJ=80&
My code splits the first string on & and uses Contains. But the duration is too long, as the big string is up to 800000 characters.
Is there a better/faster method for this?
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlInt32 EquipmentCompare(SqlString equip, SqlString comp)
{
SqlInt32 result = 1;
if (comp.IsNull)
{
result = 1;
}
else
{
string equipment = "&" + equip.ToString();
string compString = comp.ToString() + "! ";
while (compString.Length > 1)
{
string sub = compString.Substring(0, compString.IndexOf("!"));
compString = compString.Substring(compString.IndexOf("!")+1);
string[] elements = sub.Split('&');
foreach (string i in elements)
{
if (i.StartsWith("~"))
{
if (equipment.Contains("&" + i.Substring(1) + "&"))
{
result = 0;
break;
}
}
else if (!equipment.Contains("&" + i + "&"))
{
result = 0;
break;
}
else
{
result = 1;
continue;
}
}
if (result == 1)
{
break;
}
}
}
return result;
}
}
I think you may speed up your code by using HashSet. Try this:
var str1 = "A=1&AW=43&KO=96&R=7&WW=15&ZJ=80";
var str2 = "A=1&AG=77&AW=43&.....&KF=11&KO=96&.....&QW=55&R=7&....&WV=1&WW=15&....ZJ=80&";
var largeStringSet = new HashSet<string>(str2.Split('&'));
var allPartsIncluded = str1.Split('&').All(s => largeStringSet.Contains(s));
When I am programming my forum, I am having troubles in differentiating the two digits of information on my csv file.
The issue is: If, there are 2 adults who are wanting to go to a place the price = less
However is it is a single adult the price will equal more.
PROBLEM: The problem that occurs is that ALL my segments think all Adults should get charged less, when some of the transaction charges should show more.
To be precise in information: The File that contains the HolidayTran.CSV has the array[3] that has the information of 1 or 2 adults in the party.
When I carry the function ref double adult is that I am carrying to the top.
Edited - This is the method that my professor at my university wants...yes slow and stupid, but its his practice final, so I am trying to figure out what I am missing.
Yes I understand i am suppose to do my own work, but I hope someone can tell me where my math is wrong in the programming.
Edited # 2 Changed the Variables to help make it clearer. I found the isolated problem, located at the If loop section, of my equation. It has been multiplying everything by two digits instead of 1. How can I create a function where if the message reads either a 1 or a 2, then the proper math would apply?
AdultPricing This function is suppose to choose the proper math, but I tend to lose concept of how to finish off the function proper. If you look at the If loop, you can see where I go wrong...Any Ideas guys?
I am trying to do a if statement bool function, but that is currently not working...I don't know what else is needed atm..
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string[] myfile = File.ReadAllLines(#"C:\temp\customerinfo.csv");
var myquery = from mylines in myfile
let myfield = mylines.Split(',')
let names = myfield[1]
let lastname = myfield[2]
let id = myfield[0]
orderby lastname, names
select new { id, names, lastname };
foreach (var listing in myquery) { cmbcustomerinfo.Items.Add(listing.id + " " + listing.names + " " + listing.lastname); }
}
private void cmbcustomerinfo_SelectedIndexChanged(object sender, EventArgs e)
{
//recalling all private void information at the top of the combobox file, inorder to send information to the listbox.
string tempvariable = "";
string iddvariable = "";
string format1 = "{0,55}{1,5}";
string format2 = "{0,-5:d}{1,15:d}{2,20:c}{3,20:c}";
string format3 = "{0,-15}{1,35:c}{2,20:c}";
string format4 = "{0,-15}{1,72:c}";
getCustomerIDFirstName(out tempvariable, out iddvariable);
getcustomerinfo(iddvariable);
//set the required information to connect to the Holiday Transaction. Where we can connect if the ID found in Holiday Matchs the ID in CustomerInfo.CSV,
//then we can show the data of the dates and pricing of the information
string[] transaction = File.ReadAllLines(#"C:\temp\HolidayTrans.csv");
var TransactionQuery = from myLinesshown in transaction
let myfield2 = myLinesshown.Split(',')
let customerid = myfield2[0]
let datestart = myfield2[1]
let numofadults = byte.Parse(myfield2[2])
let numofkids = byte.Parse(myfield2[3])
where customerid == iddvariable
orderby datestart, customerid
select new
{
customerid,
datestart,
numofadults,
numofkids
};
foreach (var staff1 in TransactionQuery)
{
lstInvoice.Items.Clear();
lstInvoice.Items.Add("Purchase Date EndDate Adult Price Kid Price");
//set up all variables used or to be used.
string idgiven = "";
double KidsSubPricing = 0;
double AdultPricing = 0;
double singleddigit = 0;
double TwinAdultPricing = 0;
double totaladult = 0;
double subtotal = 0;
double subtotal1 = 0;
double kidpricing = 3300;
byte NumberOfDaysSpent = 0;
string EndofDays = "";
DateTime daybegin;
DateTime startthedate;
DateTime datebeginning = DateTime.Now;
//set the basic functionality to find the proper ID and date to be shown that corresponses to the person.
foreach (var transactionfound in TransactionQuery)
{
idgiven = transactionfound.customerid;
datebeginning = DateTime.Parse(transactionfound.datestart);
break;
}
//set the datetime interval to show the proper grouping later on
int xyy = datebeginning.Year;
//This is suppose to show where and how I can seperate the transaction of single and double pricing.
foreach (var transactionfound in TransactionQuery)
{
if (transactionfound.numofadults.ToString().Contains("1"))
{
singleddigit = transactionfound.numofadults;
}
if (transactionfound.numofadults.ToString().Contains("2"))
{
TwinAdultPricing = transactionfound.numofadults;
}
if (transactionfound.customerid == idgiven && DateTime.Parse(transactionfound.datestart).Year == xyy)
{
getpackagepriceinfo(transactionfound.datestart,ref singleddigit, ref TwinAdultPricing, ref NumberOfDaysSpent);
KidsSubPricing = transactionfound.numofkids * kidpricing;
//AdultPricing = transactionfound.numofadults * TwinAdultPricing;
subtotal += KidsSubPricing;
subtotal1 += AdultPricing;
daybegin = DateTime.Parse(transactionfound.datestart);
startthedate = daybegin.AddDays(NumberOfDaysSpent);
EndofDays = startthedate.ToString("d");
lstInvoice.Items.Add(string.Format(format2, daybegin, EndofDays, AdultPricing, KidsSubPricing));
}
else
{
lstInvoice.Items.Add(string.Format(format3, "Subtotal Amount",subtotal1, subtotal));
lstInvoice.Items.Add(" ");
getpackagepriceinfo(transactionfound.datestart,ref singleddigit, ref TwinAdultPricing, ref NumberOfDaysSpent);
KidsSubPricing = transactionfound.numofkids * kidpricing;
//AdultPricing = transactionfound.numofadults * singleddigit;
subtotal += KidsSubPricing;
subtotal1 += AdultPricing;
daybegin = DateTime.Parse(transactionfound.datestart);
startthedate = daybegin.AddDays(NumberOfDaysSpent);
EndofDays = startthedate.ToString("d");
lstInvoice.Items.Add(string.Format(format2, daybegin, EndofDays, AdultPricing, KidsSubPricing));
idgiven = transactionfound.customerid;
xyy = DateTime.Parse(transactionfound.datestart).Year;
}
if (idgiven == "")
{
lstInvoice.Items.Clear();
lstInvoice.Items.Add(string.Format(format1, "Sorry no Transaction Found For" + " ", tempvariable));
}
//else
//{
// lstInvoice.Items.Add(string.Format(format3, "Subtotal Amount", subtotal1, subtotal));
// lstInvoice.Items.Add("");
//}
}lstInvoice.Items.Add(string.Format(format3, "Subtotal Amount", subtotal1, subtotal));
}
}
private void getCustomerIDFirstName(out string tempp, out string idd)
{
string[] temp = cmbcustomerinfo.SelectedItem.ToString().Split(' ');
tempp = temp[1];
idd = temp[0];
}
private void getpackagepriceinfo(string date, ref double CostPerSingleAdult, ref double CostPerTwoAdults, ref byte numofdays1)
{
//set the information here, so we can recall the csv file into the main program.
string[] production = File.ReadAllLines(#"C:\temp\PackagePrice.csv");
var productQuery = from myLinesshown in production
let myfield1 = myLinesshown.Split(',')
let numofdays = byte.Parse(myfield1[0])
let startdateshown = myfield1[1]
let twinadult = myfield1[2]
let singlepricing = myfield1[3]
where startdateshown == date
select new
{
numofdays,
startdateshown,
twinadult,
singlepricing
};
//setting the factor of the private function doubles and bytes to be able to get recalled, back to the top.
foreach (var xyz in productQuery)
{
numofdays1 = xyz.numofdays;
CostPerTwoAdults = double.Parse(xyz.twinadult);
CostPerSingleAdult = double.Parse(xyz.singlepricing);
date = xyz.startdateshown;
break;
}
}
//redo the customer information, so we can recall the string of customer id inorder to recall proper functionality.
private void getcustomerinfo(string customerid){
string[] myfile = File.ReadAllLines(#"C:\temp\customerinfo.csv");
var myquery = from mylines in myfile
let myfield = mylines.Split(',')
let names = myfield[1]
let lastname = myfield[2]
let id = myfield[0]
where id == customerid
select new { id, names, lastname};}
}
}
Fix your variable names.
Refactor your code into smaller and tidier methods.
The problem becomes MUCH Clearer
You have a method called getpackagepriceinfo which takes the parameters
(string date, ref double adult, ref double single12, ref byte numofdays1)
where adult is costPerSingleAdult and single12 is costPerTwoAdults
When calling this method you have passed the variable singleddigit to the now renamed paramter costPerTwoAdults. What does that even mean? Did you realize you haven't used this variable within your code
Put code clarity first. When the code is easy to understand and working correctly, then you can start rewriting sections for speed/memory/reduced LoC/experimental language features/whatever other reason, when you do that write a comment showing the codes original intention so that when a bug gets written in to the new code you can find it quickly.
after edit
That's definitely an improvement. You can see now that you've got the number of adults for each transaction, but you've assigned this number into the variable used for pricing. I think you need to refer back to the specification, which I read as "if there are 2 adults and a two adult price, then charge the twin price. Else if there is no two adult price charge 2 * single adult price, else charge the adult price" your code should read the same.
Decimal adultPrice
if ( twoAdults && twinPrice > 0)
adultPrice = twinPrice;
else if ( twoAdults )
adultPrice = 2 * singlePrice;
else
adultPrice = singlePrice;
Note that this won't work if there are more than 2 adults. Not sure if that meets the specification
SO the new Coding is the following. Thanks to James Barrass I was able to properly fix the coding to work. The problem was the following
numberAdults = byte.Parse(Transaction.NumberofAdults);
if(numberAdults == 2)
adultpricing = AdultCost*2;
else
adultpricing = CostSingle;
Because of the following code above the entire coding is able to properly work now.
private void Form1_Load(object sender, EventArgs e)
{
string[] myfile = File.ReadAllLines(#"C:\temp\customerinfo.csv");
var myQuery = from mylines in myfile
let myfield = mylines.Split(',')
let CustomerID = myfield[0]
let CustomerFirstName = myfield[1]
let CustomerLastName = myfield[2]
orderby CustomerID, CustomerLastName, CustomerFirstName
select new {
CustomerID, CustomerFirstName, CustomerLastName
};
foreach (var customerinfo in myQuery) { cmbCustomer.Items.Add(customerinfo.CustomerID + " " + customerinfo.CustomerFirstName + " " + customerinfo.CustomerLastName); }
}
private void getCustomerFirstandID(out string customerfirst, out string idd)
{
string[] tempp = cmbCustomer.SelectedItem.ToString().Split(' ');
customerfirst = tempp[1];
idd = tempp[0];
}
private void getCustomerInfo(string StatedID)
{
string[] myfile = File.ReadAllLines(#"C:\temp\customerinfo.csv");
var myQuery = from mylines in myfile
let myfield = mylines.Split(',')
let CustomerID = myfield[0]
let CustomerFirstName = myfield[1]
let CustomerLastName = myfield[2]
where CustomerID == StatedID
select new
{
CustomerID,
CustomerFirstName,
CustomerLastName
};
}
private void getPackagePriceInfo(DateTime date, ref double CostofAdults, ref double CostofSingle, ref byte NumberofDaysShown)
{
string[] myGivenFile = File.ReadAllLines(#"C:\temp\PackagePrice.csv");
var myPackageTransaction = from myLinesGiven in myGivenFile
let myFieldShown = myLinesGiven.Split(',')
let NumberofDays = myFieldShown[0]
let StartDate = DateTime.Parse(myFieldShown[1])
let TwinAdult = myFieldShown[2]
let SingleAdult = myFieldShown[3]
where StartDate == date
select new {
NumberofDays, StartDate, TwinAdult, SingleAdult
};
foreach (var Package in myPackageTransaction) {
CostofSingle = double.Parse(Package.SingleAdult);
CostofAdults = double.Parse(Package.TwinAdult);
NumberofDaysShown = byte.Parse(Package.NumberofDays);
date = Package.StartDate;
break;
}
}
private void cmbCustomer_SelectedIndexChanged(object sender, EventArgs e)
{
string customerfirstvariable = "";
string iddvariable = "";
getCustomerFirstandID(out customerfirstvariable, out iddvariable);
getCustomerInfo(iddvariable);
string format1 = "{0,55}{1,5}";
string format2 = "{0,-5:d}{1,15:d}{2,20:c}{3,20:c}";
string format3 = "{0,25}{1,19:c}{2,20:c}";
string format4 = "{0,-15}{1,72:c}";
string[] myGivenFile1 = File.ReadAllLines(#"C:\temp\holidaytrans.csv");
var myHolidayTransaction = from myLinesGiven1 in myGivenFile1
let myFieldShown = myLinesGiven1.Split(',')
let CustomerGivenID = myFieldShown[0]
let PackageStartDate = DateTime.Parse(myFieldShown[1])
let NumberofAdults = myFieldShown[2]
let NumberofKids = myFieldShown[3]
where CustomerGivenID == iddvariable
orderby PackageStartDate
select new
{
CustomerGivenID, PackageStartDate, NumberofAdults, NumberofKids
};
lstInvoice.Items.Clear();
// foreach (var transactionfound in myHolidayTransaction) {
//set up all variables used or to be used.
string EndofDays = "";
DateTime daybegin;
DateTime startthedate;
DateTime datebeginning = DateTime.Now;
string idgiven = "";
double AdultCost = 0;
byte DaysUsed = 0;
double adultpricing = 0;
double KidsPricing = 0;
double KidsCost = 3300;
double subtotal = 0;
double totalamt = 0;
double subtotal1 = 0;
double total1 = 0;
double total = 0;
double CostSingle = 0;
byte numberAdults = 0;
double adultgiven = 0;
int xyz = 0;
foreach (var Transaction in myHolidayTransaction)
{
idgiven = Transaction.CustomerGivenID;
lstInvoice.Items.Add("Purchase Date EndDate Adult Price Kid Price");
datebeginning = Transaction.PackageStartDate;
xyz = datebeginning.Year;
break;
}
foreach (var Transaction in myHolidayTransaction)
{
if (Transaction.PackageStartDate.Year == xyz) {
getPackagePriceInfo(Transaction.PackageStartDate,ref AdultCost, ref CostSingle, ref DaysUsed);
KidsPricing = KidsCost * byte.Parse(Transaction.NumberofKids);
numberAdults = byte.Parse(Transaction.NumberofAdults);
if(numberAdults == 2)
adultpricing = AdultCost*2;
else
adultpricing = CostSingle;
subtotal += KidsPricing;
subtotal1 += adultpricing;
total += KidsPricing;
total1 += adultpricing;
daybegin = Transaction.PackageStartDate;
startthedate = daybegin.AddDays(DaysUsed);
EndofDays = startthedate.ToString("d");
lstInvoice.Items.Add(string.Format(format2, startthedate, EndofDays, adultpricing, KidsPricing));}
else
{
lstInvoice.Items.Add(string.Format(format3, "Subtotal Amount", subtotal1, subtotal));
lstInvoice.Items.Add(" ");
getPackagePriceInfo(Transaction.PackageStartDate, ref AdultCost, ref CostSingle, ref DaysUsed);
KidsPricing = KidsCost * byte.Parse(Transaction.NumberofKids);
numberAdults = byte.Parse(Transaction.NumberofAdults);
if (numberAdults == 2)
adultpricing = AdultCost * 2;
else
adultpricing = CostSingle;
subtotal = KidsPricing;
subtotal1 = adultpricing;
total += KidsPricing;
total1 += adultpricing;
daybegin =Transaction.PackageStartDate;
startthedate = daybegin.AddDays(DaysUsed);
EndofDays = startthedate.ToString("d");
lstInvoice.Items.Add(string.Format(format2, startthedate, EndofDays, adultpricing, KidsPricing));
idgiven = Transaction.CustomerGivenID;
xyz = Transaction.PackageStartDate.Year;
}}
if (idgiven == "")
{
lstInvoice.Items.Clear();
lstInvoice.Items.Add(string.Format(format1, "Sorry no Transaction Found For" + " ", customerfirstvariable));
}
else
lstInvoice.Items.Add(" ");
lstInvoice.Items.Add(string.Format(format3, "Subtotal Amount", subtotal1, subtotal));
lstInvoice.Items.Add(" ");
lstInvoice.Items.Add(string.Format(format3, "Total Amount", total1, total));
}
}
}
I am trying to read from a delimited text file, but everything is returned in in one row and one column.
My connections string is
OleDbConnection con = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
Path.GetDirectoryName(#textBox1txtPath.Text) + ";" +
"Extended Properties=\"text;HDR=YES;IMEX=1;Format=Delimited(|)\"");
And my text file reads:
ItemNumber|ProductStatus|UPC
0000012|closed|2525
Please assist
Okay, so one option would be to take a different approach. Consider the following code:
// read the entire file and store each line
// as a new element in a string[]
var lines = File.ReadAllLines(pathToFile);
// we can skip the first line because it's
// just headings - if you need the headings
// just grab them off the 0 index
for (int i = 1; i < lines.Length; i++)
{
var vals = lines[i].Split('|');
// do something with the vals because
// they are now in a zero-based array
}
This gets rid of that monstrosity of a connection string, eliminates the overhead of an Odbc driver, and drastically increases the readability of the code.
i don't know exactly what do you need, but you can do this:
if you have string str with the whole text in it you can do
string[] lines = str.Split('\n');// split it to lines;
and then for each line you can do
string[] cells = line.Split('|');// split a line to cells
if we take it to the next level we can do:
public class line
{
public int ItemNumber { get; set; }
public string ProductStatus { get; set; }
public int UPC { get; set; }
public line(string currLine)
{
string[] cells = currLine.Split('|');
int item;
if(int.TryParse(cells[0], out item))
{
ItemNumber = item;
}
ProductStatus = cells[1];
int upc;
if (int.TryParse(cells[2], out upc))
{
UPC = upc;
}
}
}
and then:
string[] lines = str.Substring(str.IndexOf("\n")).Split('\n');// split it to lines;
List<line> tblLines = new List<line>();
foreach(string curr in lines)
{
tblLines.Add(new line(curr);
}
It's right in the framework -- TextFieldParser. Don't worry about the namespace, it was originally a shim for folks converting from VB6, but it's very useful. Here's a SSCCE that demonstrates its use for a number of different delimiters:
class Program
{
static void Main(string[] args)
{
var comma = #"one,""two, yo"",three";
var tab = "one\ttwo, yo\tthee";
var random = #"onelol""two, yo""lolthree";
var parser = CreateParser(comma, ",");
Console.WriteLine("Parsing " + comma);
Dump(parser);
Console.WriteLine();
parser = CreateParser(tab, "\t");
Console.WriteLine("Parsing " + tab);
Dump(parser);
Console.WriteLine();
parser = CreateParser(random, "lol");
Console.WriteLine("Parsing " + random);
Dump(parser);
Console.WriteLine();
Console.ReadLine();
}
private static TextFieldParser CreateParser(string value, params string[] delims)
{
var parser = new Microsoft.VisualBasic.FileIO.TextFieldParser(ToStream(value));
parser.Delimiters = delims;
return parser;
}
private static void Dump(TextFieldParser parser)
{
while (!parser.EndOfData)
foreach (var field in parser.ReadFields())
Console.WriteLine(field);
}
static Stream ToStream(string value)
{
return new MemoryStream(Encoding.Default.GetBytes(value));
}
}