How can I simulate user input from a console? - c#

Im doing some challenges in HackerRank. I usually use a windows Form project in visualstudio to do the debug, but realize I lost lot of time input the test cases. So I want suggestion of a way I can easy simulate the console.ReadLine()
Usually the challenges have the cases describe with something like this:
5
1 2 1 3 2
3 2
And then is read like: using three ReadLine
static void Main(String[] args) {
int n = Convert.ToInt32(Console.ReadLine());
string[] squares_temp = Console.ReadLine().Split(' ');
int[] squares = Array.ConvertAll(squares_temp,Int32.Parse);
string[] tokens_d = Console.ReadLine().Split(' ');
int d = Convert.ToInt32(tokens_d[0]);
int m = Convert.ToInt32(tokens_d[1]);
// your code goes here
}
Right now I was thinking in create a file testCase.txt and use StreamReader.
using (StreamReader sr = new StreamReader("testCase.txt"))
{
string line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
This way I can replace Console.ReadLine() with sr.ReadLine(), but this need have a text editor open, delete old case, copy the new one and save the file each time.
So is there a way I can use a Textbox, so only need copy/paste in the textbox and use streamReader or something similar to read from the textbox?

You can use the StringReader class to read from a string rather than a file.

the solution you accepted! doesn't really emulate the Console.ReadLine(), so you can't paste it directly to HackerRank.
I solved it this way:
.
.
Just paste this class above the static Main method or anywhere inside the main class to hide the original System.Console
class Console
{
public static Queue<string> TestData = new Queue<string>();
public static void SetTestData(string testData)
{
TestData = new Queue<string>(testData.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries).Select(x=>x.TrimStart()));
}
public static void SetTestDataFromFile(string path)
{
TestData = new Queue<string>(File.ReadAllLines(path));
}
public static string ReadLine()
{
return TestData.Dequeue();
}
public static void WriteLine(object value = null)
{
System.Console.WriteLine(value);
}
public static void Write(object value = null)
{
System.Console.WriteLine(value);
}
}
and use it this way.
//Paste the Console class here.
static void HackersRankProblem(String[] args)
{
Console.SetTestData(#"
6
6 12 8 10 20 16
");
int n = int.Parse(Console.ReadLine());
string arrStr = Console.ReadLine();
.
.
.
}
Now your code will look the same! and you can test as many data as you want without changing your code.
Note: If you need more complexes Write or WriteLine methods, just add them and send them to the original System.Console(..args)

Just set Application Arguments: <input.txt
and provide in input.txt your input text.
Be careful to save the file with ANSI encoding.

Related

How to remove suffix from a word in c#?

I am trying to remove a suffix/verb tense from the words I get and return them to their original state.
For example:
play - playing
watches - watch
stopped - stop
I tried to search some information how to do it but I couldn't find any.
I tried to use Humanizer and OpenNlp but I don't know how it actually works and couldn't find any method I need from them.
public List<string> changeWord(List<string> wordss,string baseUrl)
{
string[] wordEnd = {"ing","es", "ies"};
List<string> tags = getH1AndTitleTags(baseUrl);
foreach(string tag in tags)
{
if (tag.Contains(wordEnd[0]))
{
tag.Replace("ing", "");
tags.Add(tag);
}
}
return tags;
}
I found this package: Porter2StemmerStandard. Here is the sample code:
using Porter2StemmerStandard;
class Program
{
static void Main(string[] args)
{
// Create a new stemmer
var stemmer = new EnglishPorter2Stemmer();
// Stem a word
string word = "playing";
var stemmedWord = stemmer.Stem(word);
Console.WriteLine(stemmedWord.Value); // Output: play
// Stem another word
word = "watches";
stemmedWord = stemmer.Stem(word);
Console.WriteLine(stemmedWord.Value); // Output: watch
// Stem a third word
word = "stopped";
stemmedWord = stemmer.Stem(word);
Console.WriteLine(stemmedWord.Value); // Output: stop
}
}

How to check if Parse(args) is true or false

I have code that is not throwing any error. I have used NDesk option set and added 2 string Parameters. I can see it has pulled correct names in args. But when I uses parse(args) it is not throwing an error. So I am assuming it is working.
I am trying to check if p(args) is true or false. But I can not use bool expressions to List<string>.
Any help how I can accomplish that. I want execute function if parse has correct arguments.
My code is like this
private static Regex fileNamePattern = new Regex(#"^[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}[.]pdf$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
//missing method name
{
string inputFile;
string outputFile;
var p = new OptionSet() {
{"i"," pdf file",v=>inputFile=v},{"o","index file with kws",v=>outputFile=v},
};
Console.WriteLine($"args length: {args.Length}");
Console.WriteLine($"args 0: {args[0]}");
Console.WriteLine($"args 1: {args[1]}");
p.Parse(args); //I would like to use this if(parse(args))
{
}
//
}
private static void UpdateImportIndexFile(string inputFile, string outputFile)
{
using (var dip = File.CreateText(outputFile))
{
var match = fileNamePattern.Match(Path.GetFileName(MainFilePath));
if (match.Success)
{
//create text file (outputfile);
}
}
}
Since p is an instance of a class and the parse method does not support a return to emulate in a sense the functionality of a TryParse wrap your parse in a try block
try{
val = p.Parse(args);
}catch(OptionException e){
//if false
}
For more information http://www.ndesk.org/doc/ndesk-options/NDesk.Options/OptionSet.html#M:NDesk.Options.OptionSet.Parse(System.Collections.Generic.IEnumerable{System.String})

How to complete aspx connection string from text file

I must use a text file "db.txt" which inherits the names of the Server and Database to make my connection string complete.
db.txt looks like this:
<Anfang>
SERVER==dbServer\SQLEXPRESS
DATABASE==studentweb
<Ende>
The connection string:
string constr = ConfigurationManager.ConnectionStrings["DRIVER={SQL Server}; SERVER=SERVER DATABASE=DB UID=;PWD=;LANGUAGE=Deutsch;Trusted_Connection=YES"].ConnectionString;
Unfortunatly we are only allowed to use Classic ASPX.net (C# 2.0) and not the web.config.
I've searched a lot, but found nothing close to help me.
Somebody got an Idea how to make it work?
Here is something to get you going.
In a nutshell, I put the DBInfo file through a method that reads the file line by line. When I see the line <anfang> I know the next line will be important, and when I see the line <ende> I know it's the end, so I need to grab everything in between. Hence why I came up with the booleans areWeThereYet and isItDoneYet which I use to start and stop gathering data from the file.
In this snippet I use a Dictionary<string, string> to store and return the values but, you could use something different. At first I was going to create a custom class that would hold all the DB information but, since this is a school assignment, we'll go step by step and start by using what's already available.
using System;
using System.Collections.Generic;
namespace _41167195
{
class Program
{
static void Main(string[] args)
{
string pathToDBINfoFile = #"M:\StackOverflowQuestionsAndAnswers\41167195\41167195\sample\DBInfo.txt";//the path to the file holding the info
Dictionary<string, string> connStringValues = DoIt(pathToDBINfoFile);//Get the values from the file using a method that returns a dictionary
string serverValue = connStringValues["SERVER"];//just for you to see what the results are
string dbValue = connStringValues["DATABASE"];//just for you to see what the results are
//Now you can adjust the line below using the stuff you got from above.
//string constr = ConfigurationManager.ConnectionStrings["DRIVER={SQL Server}; SERVER=SERVER DATABASE=DB UID=;PWD=;LANGUAGE=Deutsch;Trusted_Connection=YES"].ConnectionString;
}
private static Dictionary<string, string> DoIt(string incomingDBInfoPath)
{
Dictionary<string, string> retVal = new Dictionary<string, string>();//initialize a dictionary, this will be our return value
using (System.IO.StreamReader sr = new System.IO.StreamReader(incomingDBInfoPath))
{
string currentLine = string.Empty;
bool areWeThereYet = false;
bool isItDoneYet = false;
while ((currentLine = sr.ReadLine()) != null)//while there is something to read
{
if (currentLine.ToLower() == "<anfang>")
{
areWeThereYet = true;
continue;//force the while to go into the next iteration
}
else if (currentLine.ToLower() == "<ende>")
{
isItDoneYet = true;
}
if (areWeThereYet && !isItDoneYet)
{
string[] bleh = currentLine.Split(new string[] { "==" }, StringSplitOptions.RemoveEmptyEntries);
retVal.Add(bleh[0], bleh[1]);//add the value to the dictionary
}
else if (isItDoneYet)
{
break;//we are done, get out of here
}
else
{
continue;//we don't need this line
}
}
}
return retVal;
}
}
}

Writing from a list to a text file C#

How do I code the whole list into the text file with commas in between each bit of data? Currently it is creating the file newData, but it is not putting in the variables from the list. Here is what I have so far.
public partial class Form1 : Form {
List<string> newData = new List<string>();
}
Above is where I create my list. Below is where I am reading it from.
private void saveToolStripMenuItem_Click(object sender, EventArgs e) {
TextWriter tw = new StreamWriter("NewData.txt");
tw.WriteLine(newData);
buttonSave.Enabled = true;
textBoxLatitude.Enabled = false;
textBoxLongtitude.Enabled = false;
textBoxElevation.Enabled = false;
}
And below is where the variables are coming from.
private void buttonSave_Click(object sender, EventArgs e) {
newData.Add (textBoxLatitude.Text);
newData.Add (textBoxLongtitude.Text);
newData.Add (textBoxElevation.Text);
textBoxLatitude.Text = null;
textBoxLongtitude.Text = null;
textBoxElevation.Text = null;
}
While you can use String.Join as others have mentioned they're ignoring three important things:
The fact that what you're really trying to do is write a comma-separated values file
The input that you're receiving and whether or not it will have commas in it
If you sanitize your input, what the current culture on the thread is when you write it out to the file
You want to write a comma-delimited file. There's no standardized format for this, but you do have to be careful of string content, especially in your case, where you're getting user input. Consider the following input:
latitude = "39,41"
longitude = "41,20"
There are a number of countries where the comma is used as a decimal separator, so this kind of input is very possible, depending on how distributed your application is (I'd be even more concerned if this was a website, personally).
And when getting the elevation, it's absolutely possible in most other places that use a comma as the thousands separator:
elevation = 20,000
In all of the other answers, your output for the line in the file will be:
39,41,41,20,20,000
Which when parsed (assuming it will be parsed, you're creating a machine-readable format) will fail.
What you want to do is parse the content first into a decimal and then output that.
Assuming you sanitize your input like so:
decimal latitude = Decimal.Parse(textBoxLatitude.Text);
decimal longitude = Decimal.Parse(textBoxLongitude.Text);
decimal elevation = Decimal.Parse(textBoxElevation.Text);
You would then format the values so that there are no commas (if you want).
To that end, I really recommend that you want to use a dedicated CSV writer/parser (try ServiceStack's serializer on NuGet, or others, if you prefer), which accounts for commas within the content you want separated by commas.
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
TextWriter tw = new StreamWriter("NewData.txt");
tw.WriteLine(String.Join(", ", newData));
// Add appropriate error detection
}
In response to the discussion in both main answer threads, here is an example from my older code of a more robust way to handle CSV output:
The above not checked for syntax, but the key concept is String.Join.
public const string Quote = "\"";
public static void EmitCsvLine(TextWriter report, IList<string> values)
{
List<string> csv = new List<string>(values.Count);
for (var z = 0; z < values.Count; z += 1)
{
csv.Add(Quote + values[z].Replace(Quote, Quote + Quote) + Quote);
}
string line = String.Join(",", csv);
report.WriteLine(line);
}
This could be made slightly more general with an IEnumerable<object> but in the code I took this form, I didn't have the need to.
You cannot output the list just by calling tw.WriteLine(newData);
But something like this will achieve that:
tw.WriteLine(string.Join(", ", newData));
you could:
StringBuilder b = new StringBuilder();
foreach (string s in yourList)
{
b.Append(s);
b.Append(", ");
}
string dir = "c:\mypath";
File.WriteAllText(dir, b.ToString());
You have to iterate the List (not tested) or use string.Join, as the other users suggested (you need to convert your list to an array then)
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
TextWriter tw = new StreamWriter("NewData.txt");
for (int i = 0; i < newData.Count; i++)
{
tw.Write(newData[i]);
if(i < newData.Count-1)
{
tw.Write(",");
}
}
tw.close();
buttonSave.Enabled = true;
textBoxLatitude.Enabled = false;
textBoxLongtitude.Enabled = false;
textBoxElevation.Enabled = false;
}

Getting bibliographic data from text in a PDF and exporting to a window form

I use iText5 for .NET to extract text from a PDF, by using below code.
private void button1_Click(object sender, EventArgs e)
{
PdfReader reader2 = new PdfReader("Scharfetter1969.pdf");
int pagen = reader2.NumberOfPages;
reader2.Close();
ITextExtractionStrategy its = new iTextSharp.text.pdf.parser.SimpleTextExtractionStrategy();
for (int i = 1; i < 2; i++)
{
textBox1.Text = "";
PdfReader reader = new PdfReader("Scharfetter1969.pdf");
String s = PdfTextExtractor.GetTextFromPage(reader, i, its);
s = Encoding.UTF8.GetString(ASCIIEncoding.Convert(Encoding.Default, Encoding.UTF8, Encoding.Default.GetBytes(s)));
textBox1.Text = s;
reader.Close();
}
}
But I want to get bibliographic data from research paper pdf.
Here is example of data which is extrected from this pdf (in endnote format), Here's a link!
%0 Journal Article
%T Repeated temperature modulation epitaxy for p-type doping and light-emitting diode based on ZnO
%A Tsukazaki, A.
%A Ohtomo, A.
%A Onuma, T.
%A Ohtani, M.
%A Makino, T.
%A Sumiya, M.
%A Ohtani, K.
%A Chichibu, S.F.
%A Fuke, S.
%A Segawa, Y.
%J Nature Materials
%V 4
%N 1
%P 42-46
%# 1476-1122
%D 2004
%I Nature Publishing Group
But remember that this is bibliographic information, it is not available in metadata of this pdf. I want to access Article Type (%O), Title (%T), Authors (%A), Date (%D) and (%I) and show it to different assigned textbox in window form.
I am using C# if any one have any code for this, or guide me how to do this.
PDF is a one-way format. You put data in so that it renders consistently on all devices (monitors, printers, etc) but the format was never intended to pull data back out. Any and all attempts to do that will be pure guess work. iText's PdfTextExtractor works but you are going to have to piece things together based on your own arbitrary set of rules, and these rules will probably change from PDF to PDF. The supplied PDF was created by InDesign which does such a great job of making text look good that it actually makes it even harder to parse the data back out.
That said, if your PDFs are all visually consistent, you could try to pull the data out while retaining formatting and use the formatting rules to guess what is what. That post will get you some HTML formatting that you could guess at. (If this actually works I'd recommend returning something more specific than HTML but I'll leave that up to you.)
Running it against your supplied PDF shows that the title is using the font HelveticaNeue-LightExt at about 17pts so you could write a rule to look for all lines that use that font at that size and combine them together. Authors are done in HelveticaNeue-Condensed at about 10pts so that's another rule.
The below code is a modified version of the one linked to above. Its a full working C# 2010 WinForms app targeting iTextSharp 5.1.1.0. It pulls out the title and authors for the supplied PDF but you'll need to tweak it for other PDFs and meta data. See the comments in the code for specific implementation details.
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using iTextSharp.text.pdf.parser;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
PdfReader reader = new PdfReader(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "nmat4-42.pdf"));
TextWithFontExtractionStategy S = new TextWithFontExtractionStategy();
string F = iTextSharp.text.pdf.parser.PdfTextExtractor.GetTextFromPage(reader, 1, S);
//Buffers to hold various parts from the PDF
List<string> titles = new List<string>();
List<string> authors = new List<string>();
//Array of lines of text
string[] lines = F.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
//Temporary string
string t;
//Loop through each line in the array
foreach (string line in lines)
{
//See if the line looks like a "title"
if (line.Contains("HelveticaNeue-LightExt") && line.Contains("font-size:17.28003"))
{
//Remove the HTML tags
titles.Add(System.Text.RegularExpressions.Regex.Replace(line, "</?span.*?>", "").Trim());
}
//See if the line looks like an "author"
else if (line.Contains("HelveticaNeue-Condensed") && line.Contains("font-size:9.995972"))
{
//Remove the HTML tags and trim extra characters
t = System.Text.RegularExpressions.Regex.Replace(line, "</?span.*?>", "").Trim(new char[] { ' ', ',', '*' });
//Make sure we have a valid name, probably need some more exceptions here, too
if (!string.IsNullOrWhiteSpace(t) && t != "AND")
{
authors.Add(t);
}
}
}
//Write out the title to the console
Console.WriteLine("Title : {0}", string.Join(" ", titles.ToArray()));
//Write out each author
foreach (string author in authors)
{
Console.WriteLine("Author : {0}", author);
}
Console.WriteLine(F);
this.Close();
}
public class TextWithFontExtractionStategy : iTextSharp.text.pdf.parser.ITextExtractionStrategy
{
//HTML buffer
private StringBuilder result = new StringBuilder();
//Store last used properties
private Vector lastBaseLine;
private string lastFont;
private float lastFontSize;
//http://api.itextpdf.com/itext/com/itextpdf/text/pdf/parser/TextRenderInfo.html
private enum TextRenderMode
{
FillText = 0,
StrokeText = 1,
FillThenStrokeText = 2,
Invisible = 3,
FillTextAndAddToPathForClipping = 4,
StrokeTextAndAddToPathForClipping = 5,
FillThenStrokeTextAndAddToPathForClipping = 6,
AddTextToPaddForClipping = 7
}
public void RenderText(iTextSharp.text.pdf.parser.TextRenderInfo renderInfo)
{
string curFont = renderInfo.GetFont().PostscriptFontName;
//Check if faux bold is used
if ((renderInfo.GetTextRenderMode() == (int)TextRenderMode.FillThenStrokeText))
{
curFont += "-Bold";
}
//This code assumes that if the baseline changes then we're on a newline
Vector curBaseline = renderInfo.GetBaseline().GetStartPoint();
Vector topRight = renderInfo.GetAscentLine().GetEndPoint();
iTextSharp.text.Rectangle rect = new iTextSharp.text.Rectangle(curBaseline[Vector.I1], curBaseline[Vector.I2], topRight[Vector.I1], topRight[Vector.I2]);
Single curFontSize = rect.Height;
//See if something has changed, either the baseline, the font or the font size
if ((this.lastBaseLine == null) || (curBaseline[Vector.I2] != lastBaseLine[Vector.I2]) || (curFontSize != lastFontSize) || (curFont != lastFont))
{
//if we've put down at least one span tag close it
if ((this.lastBaseLine != null))
{
this.result.AppendLine("</span>");
}
//If the baseline has changed then insert a line break
if ((this.lastBaseLine != null) && curBaseline[Vector.I2] != lastBaseLine[Vector.I2])
{
this.result.AppendLine("<br />");
}
//Create an HTML tag with appropriate styles
this.result.AppendFormat("<span style=\"font-family:{0};font-size:{1}\">", curFont, curFontSize);
}
//Append the current text
this.result.Append(renderInfo.GetText());
//Set currently used properties
this.lastBaseLine = curBaseline;
this.lastFontSize = curFontSize;
this.lastFont = curFont;
}
public string GetResultantText()
{
//If we wrote anything then we'll always have a missing closing tag so close it here
if (result.Length > 0)
{
result.Append("</span>");
}
return result.ToString();
}
//Not needed
public void BeginTextBlock() { }
public void EndTextBlock() { }
public void RenderImage(ImageRenderInfo renderInfo) { }
}
}
}

Categories