How can I return following values? - c#

I'm working on my project but I can't go on. My project should generate two code parts and convert these to two hashes. Thats all working. But now, I'd like to print the values out in the browser.
Thant is my unfinished code:
The Model:
namespace myapplication.test.Backend.Models
{
public class CodeContainer
{
public string CodePartA { get; set; }
public string CodePartB { get; set; }
public string HashAB { get; set; }
public string HashBA { get; set; }
}
}
The Class where I generate my codes and hashes:
namespace myapplication.test.Backend.Utilities
{
public static class VerificationCodeUitillity
{
private static string GenerateHash(string input)
{
string hash = string.Empty;
using (MD5 md5Hash = MD5.Create())
{
byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
StringBuilder sBuilder = new StringBuilder();
for (int i = 0; i < data.Length; i++)
{
sBuilder.Append(data[i].ToString("x2"));
}
hash = sBuilder.ToString();
}
return hash;
}
private static string GenerateCodePart(int lenght)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
Random code = new Random();
return new string(Enumerable.Repeat(chars, lenght).Select(s => s[code.Next(s.Length)]).ToArray());
}
public static CodeContainer GeneratePVCode()
{
CodeContainer result = new CodeContainer();
result.CodePartA = GenerateCodePart(4);
result.CodePartB = GenerateCodePart(4);
result.HashAB = GenerateHash(result.CodePartA + result.CodePartB);
result.HashBA = GenerateHash(result.CodePartB + result.CodePartA);
return result;
}
}
}
And here in my Demo Controller I'd like to return the values CodePartA, CodePartB, HashAB and HashBA.
// GET api/demo/code
[HttpGet]
[Route("code")]
public string Code()
{
//return values here
}
Thanks for your help in advance!!
Cheers

Like that it should work:
// GET api/demo/code
[HttpGet]
[Route("code")]
public CodeContainer PVCodeGen()
{
return VerificationCodeUitillity.GeneratePVCode();
}

You should return the IHttpActionResult Interface in api-methods.
// GET api/demo/code
[HttpGet]
[Route("code")]
public IHttpActionResult PVCodeGen()
{
return this.Ok<CodeContainer>(VerificationCodeUitillity.GeneratePVCode());
}

Related

Table Row (//tr) HtmlNodes seem to have issue with rows being skipped

I'm currently trying to scrape a cannabis strain database as it is no longer being maintained. I seem to be running into an issue where table rows are skipped in my logic but it really doesn't make sense, it's like a break is being called when I'm iterating through the //tr elements of the table that is storing the chemical reports.
Is it something like the δ α symbols in the next row. I've tried regex replacing them out to now luck. Any help would be appreciated all code is in a single class console app.
Issue is in the table.ChildNodes not iterating all the way through. Located in the ParseChemical() method.
Sample Page: http://ocpdb.pythonanywhere.com/ocpdb/420/
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.Design;
using System.IO.IsolatedStorage;
using System.Linq;
using System.Linq.Expressions;
using System.Net;
using System.Net.Http;
using System.Reflection.Emit;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using HtmlAgilityPack;
using Microsoft.VisualBasic.CompilerServices;
namespace CScrape
{
class Program
{
private static readonly HttpClient Client = new HttpClient();
private static readonly string BaseUri = "http://ocpdb.pythonanywhere.com/ocpdb/";
private static int _startId = 420;
private static int _endId = 1519;
private static List<Lab> _labs = new List<Lab>();
private static List<ChemicalItem> _chemicalItems = new List<ChemicalItem>();
private static List<UnitOfMeasure> _uoms = new List<UnitOfMeasure>();
private static List<Strain> _strains = new List<Strain>();
static void Main(string[] args)
{
Client.DefaultRequestHeaders.Accept.Clear();
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls13;
_uoms.AddRange(GetUoms());
for (var i = _startId; i <= _endId; i++)
{
var result = GetUri($"{BaseUri}{i}").Result;
_strains.Add(ParseChemical(result));
}
}
private static long AddChemicalItem(ChemicalItem item)
{
if (ChemicalExists(item.Symbol))
return _chemicalItems.FirstOrDefault(ci => ci.Symbol == item.Symbol)?.Id ?? -1;
item.Id = _chemicalItems.Count + 1;
_chemicalItems.Add(item);
return item.Id;
}
private static void UpdateChemicalItem(ChemicalItem item)
{
if (!ChemicalExists(item.Symbol)) return;
var index = _chemicalItems.IndexOf(item);
if (!(index >= 0)) return;
_chemicalItems.RemoveAt(index);
AddChemicalItem(item);
}
private static long AddLab(Lab lab)
{
if (LabExists(lab.Name))
return _labs.FirstOrDefault(l => l.Name == lab.Name)?.Id ?? -1;
lab.Id = _labs.Count + 1;
_labs.Add(lab);
return lab.Id;
}
private static async Task<string> GetUri(string uri)
{
var response = await Client.GetByteArrayAsync(uri);
return Encoding.UTF8.GetString(response, 0, response.Length - 1);
}
private static Strain ParseChemical(string html)
{
html = Regex.Replace(html, #"Δ", "Delta");
HtmlDocument htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);
var strain = new Strain();
strain.Reports ??= new List<ChemicalReport>();
try
{
strain.Name = htmlDoc.DocumentNode.SelectSingleNode("/html/body/div/div[1]/div[1]/h3/b").InnerText;
}
catch (Exception e)
{
// TODO: DOcument Exception
Console.WriteLine(e.Message);
}
if (string.IsNullOrWhiteSpace(strain.Name)) return null;
try
{
var ocpId = htmlDoc.DocumentNode.SelectSingleNode("/html/body/div/div[1]/div[2]/p/b/text()[1]");
strain.OcpId = SanitizeHtml(ocpId.InnerText).Split(':')[1];
}
catch (Exception e)
{
// TODO: Document Exception
Console.WriteLine(e.Message);
}
if (string.IsNullOrWhiteSpace(strain.OcpId)) return null;
try
{
var date = htmlDoc.DocumentNode.SelectSingleNode("/html/body/div/div[1]/div[2]/p/text()");
}
catch (Exception e)
{
// TODO: Document Exception
Console.WriteLine(e.Message);
}
var chemReport = new ChemicalReport();
chemReport.Items ??= new List<ReportItem>();
try
{
var table = htmlDoc.DocumentNode.SelectSingleNode("/html/body/div/div[2]/div[1]/table/tbody");
var children = table.ChildNodes.ToList();
// On the sample page there are 200 children here
// However it only interates through the first few and then just breaks out of the loop
foreach (var child in children)
{
var name = child.Name;
if (child.Name == "tr")
{
var infos = child.SelectNodes("th|td");
foreach (var info in infos)
{
if(string.IsNullOrWhiteSpace(info.InnerText)) continue;
if (info.InnerText.Contains("Report")) continue;
if (double.TryParse(info.InnerText, out var isNumber))
{
var last = chemReport.Items.LastOrDefault();
if (last == null) continue;
if (last.Value <= 0.0000) last.Value = isNumber;
else
{
var further = chemReport.Items.ToArray()[chemReport.Items.Count - 2];
if (further.Value <= 0.0000)
further.Value = isNumber;
}
continue;
}
var _ = new ChemicalItem
{
Name = info.InnerText,
Symbol = info.InnerText
};
_.Id = AddChemicalItem(_);
var report = new ReportItem
{
Chemical = _,
ChemicalItemId = _.Id,
UnitOfMeasureId = 1,
UoM = GetUoms()[0]
};
chemReport.Items.Add(report);
}
}
}
strain.Reports.Add(chemReport);
}
catch (Exception e)
{
// TODO: Document exception
Console.Write(e.Message);
}
return strain;
}
private static List<UnitOfMeasure> GetUoms()
{
return new List<UnitOfMeasure>
{
new UnitOfMeasure {Name = "Milligrams per Gram", Symbol = "mg/g"},
new UnitOfMeasure {Name = "Percent", Symbol = "%"}
};
}
private static string SanitizeHtml(string text, string replacement = "")
{
return Regex.Replace(text, #"<[^>]+>| |α|\n|\t", replacement);
}
private static string GetLabName(string[] split)
{
var strip = split[0].Split(':')[1];
for(var i = 1; i < split.Length - 2; i ++)
{
if (string.IsNullOrWhiteSpace(split[i])) break;
strip += $" {split[i]}";
}
return strip;
}
private static string GetSampleId(string[] split)
{
var found = false;
foreach (var item in split)
{
if (found)
return item.Split(':')[1];
if (item == "Sample") found = true;
}
return "NA";
}
private static bool LabExists(string name)
{
return _labs.Any(lab => lab.Name == name);
}
private static bool ChemicalExists(string name)
{
return _chemicalItems.Any(ci => ci.Symbol == name);
}
private static ReportItem GetReportItem(string text)
{
if (string.IsNullOrWhiteSpace(text)) return null;
ReportItem ri = null;
try
{
var clean = SanitizeHtml(text);
var check = 0;
var split = clean.Split(':');
var label = split[0];
if (string.IsNullOrWhiteSpace(label)) return null;
if (double.TryParse(label, out var invalidType)) return null;
var val = string.Empty;
if (split.Length == 1)
{
if (split[0].Contains("Total"))
{
Regex re = new Regex(#"([a-zA-Z]+)(\d+)");
Match result = re.Match(split[0]);
label = result.Groups[1].Value;
val = result.Groups[2].Value;
}
}
if(split.Length > 1)
val = split[1];
if (!ChemicalExists(label)) AddChemicalItem(new ChemicalItem {Id = _chemicalItems.Count + 1,Symbol = label});
ri = new ReportItem();
ri.Chemical = _chemicalItems.FirstOrDefault(ci => ci.Symbol == label);
ri.UoM = val.Contains("%")
? _uoms.FirstOrDefault(uom => uom.Symbol == "%")
: _uoms.FirstOrDefault(uom => uom.Symbol == "mg/g");
if (string.IsNullOrWhiteSpace(val)) return ri;
var value = val.Contains("%") ? split[1].Substring(0, val.Length - 1) : val;
ri.Value = Convert.ToDouble(value);
}
catch (Exception e)
{
// TODO: Document Exception
Console.WriteLine(e.Message);
}
return ri;
}
//private static ChemicalItem GetChemicalItem(string text)
//{
//}
public class Strain
{
public long Id { get; set; }
public string Name { get; set; }
public DateTime Created { get; set; }
public string OcpId { get; set; }
public bool IsHidden { get; set; } = false;
public virtual ICollection<ChemicalReport> Reports { get; set; }
}
public class Lab
{
public long Id { get; set; }
public string Name { get; set; }
public virtual ICollection<ChemicalReport> Reports { get; set; }
}
public class ChemicalReport
{
public long Id { get; set; }
[ForeignKey("Lab")]
public long LabId { get; set; }
public virtual Lab Lab { get; set; }
public string SampleId { get; set; }
public DateTime Created { get; set; }
public virtual ICollection<ReportItem> Items { get; set; }
[ForeignKey("Strain")]
public long StrainId { get; set; }
public virtual Strain Strain { get; set; }
}
public class ChemicalItem
{
public long Id { get; set; }
public string Name { get; set; }
public string Symbol { get; set; }
}
public class ReportItem
{
public long Id { get; set; }
[ForeignKey("Chemical")]
public long ChemicalItemId { get; set; }
public virtual ChemicalItem Chemical { get; set; }
public double Value { get; set; }
[ForeignKey("UoM")]
public long UnitOfMeasureId { get; set; }
public virtual UnitOfMeasure UoM { get; set; }
}
public class UnitOfMeasure
{
public long Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Symbol { get; set; }
}
}
}

Unable to store and retrieve data from LiteDb

I am trying to write one object to LiteDb and read it back.
I have tried following code but somehow all parameters of LiteDbParamEntry object are returned as NULL or zero.
public class LiteDbParamEntry
{
[BsonId]
public int Id
{
get { return (Index * 0x100) + SubIndex; }
}
public ushort Index;
public ushort SubIndex;
public string Text;
}
public class LiteDbParamValueStorage
{
private const string _liteDbPath = "MyLiteData.db";
public LiteDbParamValueStorage()
{
WriteEntry(123, 25);
ReadEntry(123, 25);
}
public void WriteEntry(ushort index, ushort subIndex)
{
using (var db = new LiteDatabase(_liteDbPath))
{
var entry = new LiteDbParamEntry {Index = index, SubIndex = subIndex, Text = "SomeText"};
var entries = db.GetCollection<LiteDbParamEntry>("LiteDbParamEntry");
entries.Insert(entry);
}
}
public void ReadEntry(ushort index, ushort subIndex)
{
using (var db = new LiteDatabase(_liteDbPath))
{
var collection = db.GetCollection<LiteDbParamEntry>("LiteDbParamEntry");
var paramEntry = collection.FindById((index * 0x100) + subIndex);
if (paramEntry != null)
Console.WriteLine(paramEntry.Text); //paramEntry.Text is returned as Null
else
return;
}
}
}
Can somebody please point me in right direction?
Finally, i've found what's wrong with your code... You forgot to add { get; set; } instruction on the right side of field declaration ;)
Take a look here:
public class LiteDbParamEntry
{
[BsonId]
public int Id
{
get { return (Index * 0x100) + SubIndex; }
}
public ushort Index { get; set; } //getter/setter added
public ushort SubIndex { get; set; } //getter/setter added
public string Text { get; set; } //getter/setter added
}
Good luck!

Serialize data to XML and CSV

I have two problem. I need to serialize data to csv and xml but its turn out to be problematic for me.
As xml I desire to get something like:
<sentence>
<word>example1</word>
<word>example2</word>
<word>example3</word>
</sentence>
<sentence>
<word>example1</word>
<word>example2</word>
<word>example3</word>
</sentence>
My data its SentencedModel which contain inside collection of WordsModel. So it like: List<ICollection<string>>. Every position (sentence) in list have collection of string (words).
Class look like:
[Serializable]
public class WordsModel : IEnumerable<string>
{
[XmlRoot("Word")]
public ICollection<string> Words { get; set;}
public IEnumerator<string> GetEnumerator()
{
return this.Words.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.Words.GetEnumerator();
}
}
[Serializable]
public class SentencedModel : IEnumerable<WordsModel>
{
[XmlArray("Sentence"), XmlArrayItem(typeof(WordsModel), ElementName = "Words")]
public ICollection<WordsModel> Sentences { get; set; }
public SentencedModel()
{
this.Sentences = new List<WordsModel>();
}
public void Add(WordsModel words)
{
this.Sentences?.Add(words);
}
public IEnumerator<WordsModel> GetEnumerator()
{
return this.Sentences.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.Sentences.GetEnumerator();
}
}
My class which is Repositories for that:
public class WordsSeperapedBySentence
{
public SentencedModel WordsSeperatedBySentence { get; }
public WordsSeperapedBySentence()
{
this.WordsSeperatedBySentence = new SentencedModel();
}
public bool AddSentence(ICollection<string> words)
{
if (words == null) return false;
WordsModel wordsModel = new WordsModel();
wordsModel.Words = words;
this.WordsSeperatedBySentence.Add(wordsModel);
return true;
}
}
Here is my serializer class:
public class SerializeData
{
public string SerializeToXml(SentencedModel data)
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(SentencedModel));
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, data);
return textWriter.ToString();
}
}
public ToCsv(WordsSeperapedBySentence data)
{
//??
}
}
But after using
List<string> example1 = new List<string>();
example1.Add("Chris");
example1.Add("call");
example1.Add("Anna");
List<string> example2 = new List<string>();
example2.Add("Somebody");
example2.Add("call");
example2.Add("Wolf");
WordsModel words1 = new WordsModel();
WordsModel words2 = new WordsModel();
words1.Words = example1;
words2.Words = example2;
SentencedModel sentenced = new SentencedModel();
sentenced.Add(words1);
sentenced.Add(words2);
SerializeData serialize = new SerializeData();
var stringAsResult = serialize.SerializeToXml(sentenced);
Console.WriteLine(stringAsResult);
I got errors. Also I do not have idea how to storage them to CSV.
Could you help me?
Thank you in advance.
In order to save your data as CSV, you can use the following method which provides this output:
Chris,call,Anna
Somebody,call,Wolf
Each line is a sentence then all the words are separated by commas.
public string ToCsv(SentencedModel data)
{
var csvLines = data.Select(x => String.Join(",", x));
var csv = String.Join(Environment.NewLine, csvLines);
return csv;
}
I am still missing the XML part, if I do, I will edit the answer.
At least you have a part of it.
Edit Please find below the ToCsv with the fields being escaped based on the comments below.
public string ToCsv(SentencedModel data)
{
var csvLines = data.Sentences.Select(x => String.Join(",", x.Words.Select(w => EscapeForCsv(w))));
var csv = String.Join(Environment.NewLine, csvLines);
return csv;
}
private string EscapeForCsv(string input)
{
return String.Format("\"{0}\"", input.Replace("\"", "\"\"\""));
}
First: If you want to tokenize a text - I recommend:
use an array and not a list. For example: string[][]. The reason: List will locate 10%-20% more memory. You can convert a List to Array by .ToArray() (e.g. example1.ToArray) or use the C# 6.0 syntax:
string[][] sentence = new [] { {"Chris","called","Anna"}, {"Somebody","called","Wolf"} };
If possible: use the primitive datatypes - classes are to complex and slowdown your textprocessing.
Second: If you want to implement your own serializer try this approce:
public abstract class AbstractSerializer
{
public abstract void Serialize(string[][] model, string path);
}
public class XmlSerializer : AbstractSerializer
{
public override void Serialize(string[][] model, string path)
{
// your stuff
}
}
public class CsvSerializer : AbstractSerializer
{
public string LineSeparator { get; set; } = "\r\n";
public string ValueSeparator { get; set; } = ";";
public override void Serialize(string[][] model, string path)
{
var stb = new System.Text.StringBuilder();
for (int i = 0; i < model.Length; i++)
{
for (int j = 0; j < model[i].Length; j++)
{
// Example output:
// 0;0;Chris
// 0;1;call
// 0;2;Anna
// 1;0;Somebody
// 1;1;call
// 1;2;Wolf
stb.Append(string.Join(ValueSeparator, i, j, model[i][j], LineSeparator));
}
}
}
}

Variable declaration in the loop using Json

Here is my code in the controller.
public JsonResult directory()
{
List<string> alp = new List<string>();
var alp1 = new List<directories>();
string array = "";
int a = 0;
for (a = 0; a <= 25; a++)
{
int unicode = a + 65;
char character = (char)unicode;
string text1 = character.ToString();
string url1 = "<a href='/Directories/?search=" + text1 + "' 'rel=" + text1 + "'>";
string alpha = text1;
alp.Add(url1);
alphatxt.Add(alpha);
}
var alphaa = alp1.Add(new directories { arrary = url1, character = alphatxt });
return Json(alphaa, JsonRequestBehavior.AllowGet);
}
public class directories
{
public int a { get; set; }
public int unicode { get; set; }
public char character { get; set; }
public string[] arrary { get; set; }
}
Outputs are getting by
alp.Add(url1);
alp.Add(alpha);
How can i call these two outputs outside the loop.
so that i will get my output through the return
Json(alphaa, JsonRequestBehavior.AllowGet);
But I dont know how to declare the output to the variable outside the loop.
If you are trying to build a list of urls, one for each letter, then you can simply do something like:
public List<Directory> GetDirectories()
{
var dirs = new List<Directory>();
for (var ch = 'A'; ch <= 'Z'; ch++)
{
var url = string.Format(
"<a href='/Directories/?search={0}' rel='{0}'>", ch);
dirs.Add(new Directory() { Character = ch, Url = url });
}
return dirs;
}
// Directory class is simplifed a bit in this example
public class Directory
{
public char Character { get; set; }
public string Url { get; set; }
}
And then simply convert it to JSON in a separate method:
public JsonResult directory()
{
var dirs = GetDirectories();
return Json(dirs, JsonRequestBehavior.AllowGet);
}
Using LINQ, it could be simplified to:
private static readonly string Alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
public List<Directory> GetDirectories()
{
return Alphabet
.Select(ch => new Directory() { Character = ch, Url = CreateUrl(ch) })
.ToList();
}
private string CreateUrl(char ch)
{
return string.Format("<a href='/Directories/?search={0}' 'rel={0}'>", ch);
}
The way your code looks right now, it doesn't seem like you need to create this list on the server side at all (you are transferring a bunch of almost equal hard-coded URLs, which can easily be created on the client side using JavaScript), so I presume there is some additional data you are transferring with this query?
You can access the JsonResult.Data property, but I don't really think that is what you need. I suggest to create a method that return the actual result, and inside your action you call that one and serialize it as JSON:
public JsonResult directory()
{
return Json(this.GetDirectories(), JsonRequestBehavior.AllowGet);
}
private List<directories> GetDirectories()
{
... // your original code
}
I tried in many ways, At last got idea to use this way,
Also My code is shown below.
public JsonResult directory()
{
List<string> alp = new List<string>();
var alp1 = new List<directories>();
string array = "";
int a = 0;
for (a = 0; a <= 25; a++)
{
int unicode = a + 65;
char character = (char)unicode;
string text1 = character.ToString();
string url1 = "<a href='/Directories/?search=" + text1 + "' 'rel=" + text1 + "'>";
string alpha = text1;
alp.Add(url1);
alp.Add(alpha);
alp1.Add(new directories { dirurl = url1, text = alpha });
}
return Json(alp1, JsonRequestBehavior.AllowGet);
}
public class directories
{
public string text { get; set; }
public string dirurl { get; set; }
}
}
}

Parsing text file using C#

Looking for a good way to parse out of this text file, the values highlighted with the yellow boxes using C#. Each section is delineated by a TERM # which I forgot to highlight. Tried this:
string fileName = "ATMTerminalTotals.txt";
StreamReader sr = new StreamReader(fileName);
string[] delimiter = new string[] { " " };
while (!sr.EndOfStream)
{
string[] lines = sr.ReadLine().Split(delimiter, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
{
Console.WriteLine(line);
}
}
Console.ReadLine();
Safe to say I am reading lines correctly and removing "white spaces." Although, as an amateur to programming, not sure of a valid way to accurately "know" that I am getting the values from this report that I need. Any advice?
i've tested this with a very simple program to parse the given file,
basically i've created two basic classes, a page class holding a collection of terminal report class (the tran type rows)
these rows maybe even can be represented as transaction and a billing class too
first parsed the data, setting the parameters needed and lastly just accessing the properties
just rushed it to be as simple as possible, no error handling etc... its just to give you a sense of how id start solving these kind of tasks, hope it helps
Adam
namespace TerminalTest
{
class Program
{
public class TerminalReport
{
public string Word { get; set; }
public int Denials { get; set; }
public int Approvals { get; set; }
public int Reversals { get; set; }
public double Amount { get; set; }
public int ON_US { get; set; }
public int Alphalink { get; set; }
public int Interchange { get; set; }
public int Surcharged { get; set; }
public static TerminalReport FromLine(string line)
{
TerminalReport report = new TerminalReport();
report.Word = line.Substring(0, 11);
line = line.Replace(report.Word, string.Empty).Trim();
string[] split = line.Split(' ');
int i = 0;
// transaction summary
report.Denials = int.Parse(split[i++]);
report.Approvals = int.Parse(split[i++]);
report.Reversals = int.Parse(split[i++]);
report.Amount = double.Parse(split[i++]);
// billing counts
report.ON_US = int.Parse(split[i++]);
report.Alphalink = int.Parse(split[i++]);
report.Interchange = int.Parse(split[i++]);
report.Surcharged = int.Parse(split[i++]);
return report;
}
}
public class TerminalPage
{
public int PageNumber { get; set; }
public double TotalSurcharges { get; set; }
public List<TerminalReport> Rows { get; set; }
public TerminalPage(int num)
{
PageNumber = num;
Rows = new List<TerminalReport>();
}
public int TotalDenials
{
get
{
return rows.Sum(r => r.Denials);
}
}
public int TotalApprovals
{
get
{
return Rows.Sum(r => r.Approvals;
}
}
public int TotalReversals
{
get
{
return Rows.Sum(r => r.Reversals;
}
}
public double TotalAmount
{
get
{
return Rows.Sum(r => r.Amount);
}
}
public int TotalON_US
{
get
{
return Rows.Sum(r => r.ON_US);
}
}
public int TotalAlphalink
{
get
{
return Rows.Sum(r => r.Alphalink);
}
}
public int TotalInterchange
{
get
{
return Rows.Sum(r => r.Interchange);
}
}
public int TotalSurcharged
{
get
{
return Rows.Sum(r => r.Surcharged);
}
}
}
private static string CleanString(string text)
{
return Regex.Replace(text, #"\s+", " ").Replace(",", string.Empty).Trim();
}
private static List<TerminalPage> ParseData(string filename)
{
using (StreamReader sr = new StreamReader(File.OpenRead(filename)))
{
List<TerminalPage> pages = new List<TerminalPage>();
int pageNumber = 1;
TerminalPage page = null;
bool parse = false;
while (!sr.EndOfStream)
{
string line = sr.ReadLine();
line = CleanString(line);
if (line.StartsWith("TRAN TYPE"))
{
// get rid of the ----- line
sr.ReadLine();
parse = true;
if (page != null)
{
pages.Add(page);
}
page = new TerminalPage(pageNumber++);
}
else if (line.StartsWith("="))
{
parse = false;
}
else if (line.StartsWith("TOTAL SURCHARGES:"))
{
line = line.Replace("TOTAL SURCHARGES:", string.Empty).Trim();
page.TotalSurcharges = double.Parse(line);
}
else if (parse)
{
TerminalReport r = TerminalReport.FromLine(line);
page.Rows.Add(r);
}
}
if (page != null)
{
pages.Add(page);
}
return pages;
}
}
static void Main(string[] args)
{
string filename = #"C:\bftransactionsp.txt";
List<TerminalPage> pages = ParseData(filename);
foreach (TerminalPage page in pages)
{
Console.WriteLine("TotalSurcharges: {0}", page.TotalSurcharges);
foreach (TerminalReport r in page.Rows)
Console.WriteLine(r.Approvals);
}
}
}
}
I'm not sure I'd split it by spaces actually.. the textfile looks like its split into columns. You might want to read like 10 chars (or whatever the width of the column is) at a time... and I'd parse the whole file into a dictionary so you get entries like
dict["WDL FRM CHK"]["# DENIALS"] = 236
then you can easily retrieve the values you want from there, and if you ever need more values in the future, you've got them.
Alternatively, you can use regexs. You can grab the first value with a regex like
^WDL FRM CHK\s+(?<denials>[0-9,]+)\s+(?<approvals>[0-9,]+)$
using
m.Groups["approvals"]
anyway I recommend you to wrap your StreamReader with using block:
using (StreamReader sr = new StreamReader(fileName))
{
// do stuff
}
Read more on MSDN
Given that it seems to have a standard, regular format, I would use regular expressions. You can check the starting code to figure out what row you're on, then an expression that will parse out the numbers and ignore whitespace will, very likely, be easier than handling it manually.
using System;
using System.Text.RegularExpressions;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
Regex exp = new Regex(#"WDL FRM CHK(\s)+[1-9,]+(\s)+(?<approvals>[1-9,]+)(\s)+");
string str = "WDL FRM CHK 236 1,854 45,465 123 3";
Match match = exp.Match(str);
if (match.Success)
{
Console.WriteLine("Approvals: " + match.Groups["approvals"].Value);
}
Console.ReadLine();
}
}
}
Apdated from the following article to parse one of your numbers:
How to match a pattern by using regular expressions and Visual C#

Categories