Does anyone have c# code to use betfair api? - c#

I am creating a c# windows app to display current sports market rates using betfair exchange webservice, I used the
getmarketpricescompressed()
method which returns a price string that looks like this:
106093239~GBP~ACTIVE~0~1~~true~5.0~1343114432333~~N:7337~1~6992.56~2.16~~~false~~~~|2.16~1036.19~L~1~2.14~97.18~L~2~2.12~5.0~L~3~|2.18~467.36~B~1~2.2~34.12~B~2~2.22~162.03~B~3~:414464~2~102181.96~1.86~~~false~~~~|1.85~2900.33~L~1~1.84~1831.59~L~2~1.83~1593.73~L~3~|1.86~58.83~B~1~1.87~1171.77~B~2~1.88~169.15~B~3~
i don't know how to properly unpack this string, for now i am using this code:
GetMarketPricesCompressedReq price_req1 = new GetMarketPricesCompressedReq();
price_req1.header = header2;
price_req1.marketId = marketid_temp;
price_req1.currencyCode = "GBP";
GetMarketPricesCompressedResp price_resp = new GetMarketPricesCompressedResp();
price_resp = bfg2.getMarketPricesCompressed(price_req1);
//MessageBox.Show(price_resp.errorCode.ToString());
//richTextBox1.Text = "";
//richTextBox1.Text = price_resp.marketPrices;
string prices = price_resp.marketPrices;
richTextBox1.Text = price_resp.marketPrices;
string[] ab1 = prices.Split('|');
string[] temp = ab1[1].Split('~');
textBox3.Text = temp[0];
textBox4.Text = temp[4];
textBox5.Text = temp[8];
temp = ab1[2].Split('~');
textBox6.Text = temp[0];
textBox7.Text = temp[4];
textBox8.Text = temp[8];
temp = ab1[3].Split('~');
textBox9.Text = temp[0];
textBox10.Text = temp[4];
textBox11.Text = temp[8];
temp = ab1[4].Split('~');
textBox12.Text = temp[0];
textBox13.Text = temp[4];
textBox14.Text = temp[8];
if (ab1.Length >5)
{
temp = ab1[5].Split('~');
textBox15.Text = temp[0];
textBox16.Text = temp[4];
textBox17.Text = temp[8];
temp = ab1[6].Split('~');
textBox18.Text = temp[0];
textBox19.Text = temp[4];
textBox20.Text = temp[8];
}
It works fine for a few matches, but i observed the string changes for a few other matches and it thus generates exceptions,
Can any1 help me with a proper code to unpack this string, i've googled it and found a vb code, which was not very usefull,
and btw, i want to arrange the data in something like this:

Consider the following:
a|b|c|d
In this, you have four chunks. But it doesn't necessarily have to be only four. It can be two, it can be six.
Try going at it by iterating the string-array you get as a result of the
string[] ab1 = prices.Split('|');
Something like
foreach(var stringChunk in ab1)
{
string[] temp = stringChunk.Split('~');
// use the strings here as you please
}
Consider using a more dynamic approach in presenting your data as well, using a row-based, repeating control instead of static textboxes. =)
The full documentation for the compressed data is available here: https://docs.developer.betfair.com/betfair/#!page=00008360-MC.00008307-MC

Just guessing, I think the data is organised like this
first delimited by : then | we get
106093239~GBP~ACTIVE~0~1~~true~5.0~1343114432333~~N
7337~1~6992.56~2.16~~~false~~~~
2.16~1036.19~L~1~2.14~97.18~L~2~2.12~5.0~L~3~
2.18~467.36~B~1~2.2~34.12~B~2~2.22~162.03~B~3~
414464~2~102181.96~1.86~~~false~~~~
1.85~2900.33~L~1~1.84~1831.59~L~2~1.83~1593.73~L~3~
1.86~58.83~B~1~1.87~1171.77~B~2~1.88~169.15~B~3~
I think that first row is clearly a header, that first number being the market ID perhaps.
Likewise, the first part of each subsequent section is a row identifier. Delimited by ~ something like
(SelectionId)7337 (Order)1 (TotalMatched?)6992.56 (EvenPoint)2.16 (???)false
I think the price rows are delimited by ~ in tuples of 4, like this
(Price)2.16 (MatchAvailable)1036.19 (Type)L (Order)1
(Price)2.14 (MatchAvailable)0097.18 (Type)L (Order)2
(Price)2.12 (MatchAvailable)0005.00 (Type)L (Order)3
for example.
To test my guesses I'd have to compare with the BetFair rendering on thier web site.

I converted the vb code to c# myself, if anyone might find it useful, I am posting it here:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
namespace stock
{
class UnpackMarketPricesCompressed : stock.BFExchangeService.MarketPrices
{
//The substitute code for "\:"
private const string ColonCode = "&%^#";
//Unpack the string
public UnpackMarketPricesCompressed(string MarketPrices)
{
string[] Mprices = null;
string[] Part = null;
string[] Field = null;
int n = 0;
Mprices = MarketPrices.Replace("\\:", ColonCode).Split(':');
//Split header and runner data
Field = Mprices[0].Replace("\\~", "-").Split('~');
//Split market data fields
marketId = Convert.ToInt32(Field[0]);
//Assign the market data
currencyCode = Field[1];
marketStatus = (stock.BFExchangeService.MarketStatusEnum)Enum.Parse(typeof(stock.BFExchangeService.MarketStatusEnum), Field[2], true);
delay = Convert.ToInt32(Field[3]);
numberOfWinners = Convert.ToInt32(Field[4]);
marketInfo = Field[5].Replace(ColonCode, ":");
discountAllowed = (Field[6].ToLower() == "true");
marketBaseRate = float.Parse(Field[7]);
lastRefresh = long.Parse(Field[8]);
removedRunners = Field[9].Replace(ColonCode, ":");
bspMarket = (Field[10] == "Y");
n = Mprices.Length - 1;
// ERROR: Not supported in C#: ReDimStatement
//For each runner
for (int i = 0; i <= n; i++)
{
Part = Mprices[i + 1].Split('|');
//Split runner string into 3 parts
Field = Part[0].Split('~');
//Split runner data fields
runnerPrices[i] = new stock.BFExchangeService.RunnerPrices();
var _with1 = runnerPrices[i];
//Assign the runner data
_with1.selectionId = Convert.ToInt32(Field[0]);
_with1.sortOrder = Convert.ToInt32(Field[1]);
_with1.totalAmountMatched = Convert.ToDouble(Field[2]);
_with1.lastPriceMatched = Convert.ToDouble(Field[3]);
_with1.handicap = Convert.ToDouble(Field[4]);
_with1.reductionFactor = Convert.ToDouble(Field[5]);
_with1.vacant = (Field[6].ToLower() == "true");
_with1.farBSP = Convert.ToDouble(Field[7]);
_with1.nearBSP = Convert.ToDouble(Field[8]);
_with1.actualBSP = Convert.ToDouble(Field[9]);
_with1.bestPricesToBack = Prices(Part[1]);
_with1.bestPricesToLay = Prices(Part[2]);
}
}
private stock.BFExchangeService.Price[] Prices(string PriceString)
{
string[] Field = null;
stock.BFExchangeService.Price[] Price = null;
int k = 0;
int m = 0;
Field = PriceString.Split('~');
//Split price fields
m = (Field.Length / 4) - 1;
//m = number of prices - 1
// ERROR: Not supported in C#: ReDimStatement
for (int i = 0; i <= m; i++)
{
Price[i] = new stock.BFExchangeService.Price();
var _with2 = Price[i];
_with2.price = Convert.ToInt32(Field[k + 0]);
//Assign price data
_with2.amountAvailable = Convert.ToInt32(Field[k + 1]);
_with2.betType = (stock.BFExchangeService.BetTypeEnum)Enum.Parse(typeof(stock.BFExchangeService.BetTypeEnum), Field[k + 2], true);
_with2.depth = Convert.ToInt32(Field[k + 3]);
k += 4;
}
return Price;
//Return the array of prices
}
}
}

Related

how to find average with strings c#

I need to set a variable as the average of 3 other variables, which are numbers but they are set as strings. How do I do this? I'm using c#, visual studio, windows forms.
The variable i'm trying to set is called skiTime, the variables i'm using to get the average are called skiTime1, skiTime2 and skiTime3.
basically i need the c# version of: skiTime = (skiTime1 + skiTime2 + skiTime3) / 3
The code where I start (declare? I don't know the word to use) the variables
List<string> skiTime1 = new List<string>();
List<string> skiTime2 = new List<string>();
List<string> skiTime3 = new List<string>();
string skiTime
The code where i set the value for the variables:
using (StreamReader sr = new StreamReader("pupilSkiTimes.txt"))
{
string line = "";
while ((line = sr.ReadLine()) != null)
{
string[] components = line.Split("~".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
skiTime1.Add(components[2]);
skiTime2.Add(components[3]);
skiTime3.Add(components[4]);
}
sr.Close();
}
I need to display skiTime1, skiTime2 and skiTime3 in a data grid view, so i think they need to be strings, if i'm not mistaken. skiTime will only be used in another calculation so maybe it can be turned into an int. I don't really know what i'm doing and only got this far because of tutorials, help.
I can post the whole code if this question is too confusing or doesn't have enough information.
public string CalculateAverage(List<string> skiTime1, List<string> skiTime2, List<string> skiTime3)
{
List<string> allValues = new List<string>();
allValues.AddRange(skiTime1);
allValues.AddRange(skiTime2);
allValues.AddRange(skiTime3);
float totalcount = 0;
float average = 0;
foreach (var value in allValues)
{
totalcount = totalcount + float.Parse(value);
}
average = totalcount / allValues.Count();
return average.ToString();
}
Function for returning the average value
Now call the function where u need like:
string skiTime = CalculateAverage(skiTime1, skiTime2, skiTime3);
You need to parse the strings to decimals then calculate the average:
List<decimal> avgTime = new List<decimal>();
for (var i = 0; i < skiTime1.Length; i++) {
var avg = (decimal.Parse(skiTime1[i]) + decimal.Parse(skiTime2[i]) + decimal.Parse(skiTime3[i])) / 3;
avgTime.Add(avg);
}

Is there a way to add multiple variables together without implicitly declaration

I have 23 int variables that get assigned value upon form load, is there a shortcut to add them together without implicit addition.
I.E VarAns = Var1 + Var2 + Var3.... + Var 23.
MathsGrp1 = Convert.ToInt32(textBoxMathsGrp1.Text);
MathsGrp3 = Convert.ToInt32(textBoxMathsGrp3.Text);
MathsGrp2 = Convert.ToInt32(textBoxMathsGrp2.Text);
MathsGrp4 = Convert.ToInt32(textBoxMathsGrp4.Text);
EnglishGrp1 = Convert.ToInt32(textBoxEnglishGrp1.Text);
EnglishGrp2 = Convert.ToInt32(textBoxEnglishGrp3.Text);
EnglishGrp3 = Convert.ToInt32(textBoxEnglishGrp2.Text);
EnglishGrp4 = Convert.ToInt32(textBoxEnglishGrp4.Text);
Construction = Convert.ToInt32(textBoxConstruction.Text);
PSD = Convert.ToInt32(textBoxPSD.Text);
Careers = Convert.ToInt32(textBoxCareers.Text);
ASDAN = Convert.ToInt32(textBoxASDAN.Text);
Music = Convert.ToInt32(textBoxMusic.Text);
Spare = Convert.ToInt32(textBoxSpare.Text);
Art = Convert.ToInt32(textBoxArt.Text);
Science = Convert.ToInt32(textBoxScience.Text);
PEGrp1 = Convert.ToInt32(textBoxPEGrp1.Text);
PEGrp2 = Convert.ToInt32(textBoxPEGrp2.Text);
ICT = Convert.ToInt32(textBoxICT.Text);
HairDressing = Convert.ToInt32(textBoxHairDressing.Text);
CookingGrp1 = Convert.ToInt32(textBoxCookingGrp1.Text);
CookingGrp2 = Convert.ToInt32(textBoxCookingGrp2.Text);
CookingGrp3 = Convert.ToInt32(textBoxCookingGrp3.Text);
// int Check = insert Long list of variables here
P.S i know theres a better way to initilise and convert the textbox strings into integers but i want to keep it simple.
public void Function()
{
List<int> Collection = new List<int>();
Collection.Add(1);
Collection.Add(2);
Collection.Add(3);
Collection.Add(7);
Collection.Add(9);
Collection.Add(5);
Collection.Add(25);
foreach (int Elem in Collection)
{
int Result = 0;
Result = Result + Elem;
}
}

Create Bing maps v8 polygon from lookup files

I have two files (fileA.txt and fileB.txt) that I need to use to create polygons on a map. FileA contains the list of reference numbers that refer to fileB. I am able to get that list from A and find the corresponding file in B using streamreader. What I can not seem to grab is the data that I need from that file.
FileA looks like:
|ADV|170613/0448|170613/0600|KRIW||0|1
WYZ023 500230 Star_Valley
WYZ013 500130 Jackson_Hole
I take the number in bold, 500230, and look for it in fileB which looks like this:
|FIPS|500230|
8 59.094 59.091 -138.413 -138.425 59.091 -138.413 59.092 -138.425 59.094 -138.415 59.091 -138.413
8 59.101 59.099 -138.397 -138.413 59.099 -138.405
59.101 -138.413 59.100 -138.397 59.099 -138.405
|FIPS|500231|
Each line that starts with 8 after the |FIPS| line is one polygon. The number 8 represents the number of lat long pairs AFTER the numbers in bold. This 8 can be anywhere from 4 to 20. I can also have anywhere from 1 to 20 of these "groups" of lat long pairs within each |FIPS|.
In the end, I'm trying to get a list of lat long pairs for each |FIPS| that equals the |FIPS| that is looked up.
or an array of arrays. Any thoughts?
UPDATE: this is what I came up with but Im getting stuck on mainListLoop. The streamReader only reads to the end of the line but I need it to read to the next FIPS. Any suggestions?
[HttpGet]
public ActionResult GetWinterData()
{
var winterFilePaths = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["WatchWarnFilePath"] + "/wstm.txt");
var stringData = new List<string>();
var mainList = new List<WinterModel>();
using (var reader = new StreamReader(winterFilePaths))
{
while (!reader.EndOfStream)
{
var data = reader.ReadLine().Trim();
if (!string.IsNullOrEmpty(data))
stringData.Add(data);
}
reader.Close();
}
WinterModel temp = null;
stringData.ForEach(line =>
{
if (line.StartsWith("|"))
{
if (temp != null)
{
mainList.Add(temp);
}
string[] rawData = line.Split('|');
temp = new WinterModel
{
Type = rawData[0],
PolyBorderColor = GetBorderColor(rawData[0], types.WINTER),
PolyBorderThickness = GetPolyBorderThickness(rawData[0], types.WINTER),
StartDateTime = rawData[1],
EndDateTime = rawData[2],
innerData = new List<tempInnerWinterModel>(),
InfoboxTitle = GetInfoboxTitle(rawData[0], types.WINTER)
};
}
else
{
string[] tempLine = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
temp.innerData.Add(new tempInnerWinterModel
{
param1 = tempLine[0],
FIPS = tempLine[1],
Location = tempLine[2],
latLongs = new List<lat_longPairs>()
});
}
});
mainList.Add(temp);
getWinterLatLongPairs2(mainList);
var tempJson = (from item in stringData
select item.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
into rawData
select new WatchPolygons
{
Type = rawData[0],
PolyBorderColor = GetBorderColor(rawData[0], types.WINTER),
StartDateTime = rawData[1],
EndDateTime = rawData[2],
//Lat_Long_Pairs = getWinterLatLongPairs2(rawData[5])
//Metadata = "Watch Type: " + rawData[0] + "< /br>" + "Watch Start: " + rawData[1] + ' ' + rawData[2]
// + "< /br>" + "Watch End: " + rawData[3] + ' ' + rawData[4]
});
return Json((from item in stringData
select item.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries)
into rawData
select new WatchPolygons
{
Type = rawData[0],
PolyBorderColor = GetBorderColor(rawData[0], types.WINTER),
StartDateTime = rawData[1],
EndDateTime = rawData[2],
//Lat_Long_Pairs = getWinterLatLongPairs2(rawData[5])
//Metadata = "Watch Type: " + rawData[0] + "< /br>" + "Watch Start: " + rawData[1] + ' ' + rawData[2]
// + "< /br>" + "Watch End: " + rawData[3] + ' ' + rawData[4]
}).ToList(), JsonRequestBehavior.AllowGet);
}
private static void getWinterLatLongPairs2(List<WinterModel> inputFips)
{
var searchFips = inputFips;
var fipFilePath = HostingEnvironment.MapPath(ConfigurationManager.AppSettings["WatchWarnFilePath"] + "/pfzbnds.tbl");
var stringInnerData = new List<string>();
using (var reader = new StreamReader(fipFilePath))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine().Trim();
if (!string.IsNullOrEmpty(line) && line.Contains("<FIPS>"))
{
MainListLoop(inputFips, line, reader);
if (inputFips.Last().innerData.Last().latLongs.Count > 0)
{
return;
}
}
}
reader.Close();
}
return;
}
private static void MainListLoop(List<WinterModel> inputFips, string line, StreamReader reader)
{
inputFips.ForEach(main =>
{
main.innerData.ForEach(fips =>
{
if (line.Contains(fips.FIPS))
{
var line2 = reader.ReadLine().Trim();
fips.param1 = "CHANGE";
string[] tempLine = line2.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
string numLatLongPairs = tempLine[0];
var latLonPairsWint = new List<lat_longPairs>();
int endIndex = ((Int16.Parse(numLatLongPairs) * 2) + 3 - 1);
//grab each pair of lat/longs starting at the 5th and add them to the array
for (int i = 5; i < endIndex; i += 2)
{
fips.latLongs.Add(new lat_longPairs { latitude = decimal.Parse(tempLine[i]), longitude = decimal.Parse(tempLine[i + 1]) });
}
return;
}
});
});
}
Not 100% clear on the file format of A, but if fileB isn't massive, I would recommend parsing fileB first into a dictionary where the key is the fips code and the value is a array of array of lat,long pairs, or whatever coordinate object you have in your application (numbers work fine too). From there when parsing fileA, when ever you come across a fips value, check the dictionary. This would be the easiest implementation.
If however fileB is massive, then memory on your computer or server (where you are parsing this), may be an issue. Or if fileA only references a small subset of data in fileB, then parsing all the data in fileB likely isn't the greatest. In these case, parse fileA and get a list of fips code. Next, scan through fileB until you find a fips code and see if it is in your list from fileA. If it is, parse that data from fileB and remove that value from your fileA list. Continue this until all fips in the filaA list are removed or you reach the end of fileB. For scanning fileB, you can write a custom stream reader, or if the file isn't massive, read the whole thing as a string, then use the index and substring to skip through fileB looking for fips.

Having troubles with my math in the program

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));
}
}
}

Get first value in column from CSV file in C#

I am using this code in my Web Api to get data from a csv file, and plug that data into a Item List.
private List<Item> ietms = new List<Item>();
public ItemRepository()
{
string filename = HttpRuntime.AppDomainAppPath + "App_Data\\items.csv";
var lines = File.ReadAllLines(filename).Skip(1).ToList();
for (int i = 0; i < lines.Count; i++)
{
var line = lines[i];
var columns = line.Split('$');
//get rid of newline characters in the middle of data lines
while (columns.Length < 9)
{
i += 1;
line = line.Replace("\n", " ") + lines[i];
columns = line.Split('$');
}
//Remove Starting and Trailing open quotes from fields
columns = columns.Select(c => { if (string.IsNullOrEmpty(c) == false) { return c.Substring(1, c.Length - 2); } return string.Empty; }).ToArray();
items.Add(new Item()
{
Id = int.Parse(columns[0]),
Name = columns[1],
Description = columns[2],
Price = string.IsNullOrEmpty(columns[3].Trim()) ? null : (double?)double.Parse(columns[3]),
Weight = columns[8],
PhotoUrl = columns[7],
Category=columns[9]
});
}
}
In the csv file one of the columns/value is structured like this:
Groups>Subgroup>item
or in some cases
MajorGroup|Groups>Subgroup>item
How do I pull out only the first value before the > or |, so that I would get the value as Groups in the first case and MajorGroup in the second, and store it in the Category property in the Item List, which is now just set to the entire value in column 9 which would return the whole string "Groups>Subgroup>item".
Add the following line before calling "Add item"
var temp = columns[9].Split('|', '>');
Then assign the category as follows.
Category = temp[0];
Based on: MSDN String Method Documentation
Did you mean something like this?
string data = "MajorGroup|Groups>Subgroup>item";
string groupOrCategory;
if (data.Contains('|'))
{
groupOrCategory = data.Substring(0, data.IndexOf('|'));
}
else
{
groupOrCategory = data.Substring(0, data.IndexOf('>'));
}
Console.WriteLine(groupOrCategory);

Categories