Sub-string case - c#

After reading a web-page i got the following text.
Weekend of March 23 - 25, 2018
Title
Weekend
Gross
Weeks
Pacific Rim: Uprising
$28.1M
$17M
1
Spider Man: Home Coming
$37.8M
$12M
3
My problem is that i can't get all titles just like
Pacific Rim: Uprising & Spider Man: Home Coming (in this example) so do you suggest any solution for that, i really tried a lot of codes but nothing worked for me, it seems to be so hard since i can't depend on something for example it would be easier to copy what goes after "title:" and stop when there is empty line.
Update
i have figured out that all titles can be found on lines number 30,46,62... but how to write a code that copies specific lines! can you help me with that?

What you need is a parser. But, in order to parse text, there has to be some underlying structure present. Luckily, there is just enough in this case to be serviceable.
Pacific Rim: Uprising
$28.1M
$17M
1
Spider Man: Home Coming
$37.8M
$12M
3
Each movie entry consists of a single identifying pattern: 2 lines that contain "$" signs, followed by a simple integer. So a simple solution consists of 2 methods: a method to read all the contents of the file, one line at a time, and a method to parse a movie entry, once it is located:
public class Movie
{
public string Title {get;set;}
public decimal Gross {get;set;}
public decimal Weekly {get;set;}
public int Weeks {get;set;}
}
public void ReadMovies()
{
List<Movie> movies = new List<Movie>();
string[] lines = File.ReadAllLines("movies.txt");
int cursor = 0;
while (cursor < lines.Length)
{
if (lines[cursor].Contains("$"))
{
movies.Add(ParseMovie(lines, ref cursor));
}
cursor++;
}
}
public Movie ParseMovie(string[] lines, ref int cursor)
{
Movie result = new Movie();
// this method is called when we reach the gross dollar figure, so
// we have to back up to get the title
result.Title = lines[--cursor];
// these lines assume that the parse methods will succeed; if the
// underlying structure of the text is more uncertain, these should be
// replaced with the 'TryParse' pattern
result.Gross = decimal.Parse(lines[++cursor].Trim('$', 'M'));
result.Weekly = decimal.Parse(lines[++cursor].Trim('$', 'M'));
result.Weeks = int.Parse(lines[++cursor]);
// we return from this method with the cursor on the last line
// of the movie entry -- this will be incremented when we return
// in the ReadMovies method
return result;
}

The solution is based on a few assumptions :
You have a list of all the movies(not the HTML/retrieved movies but a list of all movies released)
You have list(the html file-as u mentioned) that has movie titles and details , line after line,one below the other
Firstly get the names of all the movies.Google for it and add them to a text file.Then read the text file and add the names/titles to a list.Then we create a list of the retrieved movie names.Then we compare two lists for matches and return the title(match)
Follow the below code snippet :
List<string> movieList = new List<string>;
movieList.Add(File.ReadAllLines("C:\\movies.txt"));
List<string> retrievedList = new List<string>; ///The list of retrieved movie list
retrievedList.Add(File.ReadAllLines("C:\\retrievedmovies.html"));
foreach (var item in retrievedList)
{
if (movieList.Contains(item) == true)
{
continue;
MessageBox.Show(item)
}
else
{
}
}
Hope this helps...If it doesn't , please leave a comment before down-voting

Related

Making a simple change function for a database app C#

Sorry if this is an ultra beginner question but, I need to be able to change all field values except the item number by giving its item number not array index. I already have a add and delete feature.
using System;
struct ItemData
{
public int ItemNumber;
public string Description;
public double PricePerItem;
public int QuantityOnHand;
public double OurCostPerItem;
public double ValueOfItem;
}
class Program
{
public static void Main()
{
int invItems = 0;
var items = new ItemData[10];
while (true)
{
Console.Write("1. Add, 2. Change, 3. Delete, 4. List:");
string strx = Console.ReadLine();
var choice = int.Parse(strx);
Console.WriteLine();
switch (choice)
{
This is what I have so far but not sure where to start
case 2: //change items
{
Console.Write("Please enter an item ID No:");
string input = Console.ReadLine();
int changeItemNumber = int.Parse(input);
bool foundItem = false;
for (int x = 0; x < invItems; x++)
{
if (items[x].ItemNumber == changeItemNumber)
{
//code
}
}
if (!foundItem)
{
Console.WriteLine("Item {0} not found", changeItemNumber);
}
break;
}
It's still a little unclear what you're asking so if this is wide of the mark then feel free to let me know.
Start by mapping out the flow of the process and then implement one piece at a time. Here's a basic series of operations you'll want to do, not necessarily in this order:
Input ItemNumber.
Find index of matching record in array.
If not found report error and stop.
Get record from user.
Set ItemNumber in record to entered value.
Store record in array at same index as original.
If you think about the way the rest of the program works you should see that some of those parts - maybe most of them - are already done somewhere in your code. Your add operation probably already has the Get record from user code. Your delete operation probably has Input ItemNumber and Find index of matching record in array done already.
So pull those parts out into methods and reuse them where it makes sense. Anywhere you're writing the same code multiple times with minor changes try to see if you can extract the code into a small method you can call with maybe some parameters. Your "input a number" code for instance - used for operation selection, item number entry and presumably whatever you're doing for delete - can be pulled out to a supporting method like this one:
static int InputNumber(string prompt)
{
Console.Write($"{prompt}: ");
var inputText = Console.ReadLine();
return int.Parse(inputText);
}
Now when you want to change the way you're doing number input you have a central place to make the changes and you don't have to worry about tracking down all the places you wrote the same code.
The same goes for the rest of the pieces. When two operations share some of the same code then pull that code out to supporting methods. Finding the index of an item in the array by some criteria can - and should - be one of those:
// Return array index of matching item or -1 if not found
int ItemIndex(int itemNumber)
{
for (int i = 0; i < invItems; i++)
{
if (items[i].ItemNumber == itemNumber)
return i;
}
return -1;
}
Likewise the code - whatever that looks like - that your add operation uses to get a record from the user.
Once you do that your change item case looks a lot simpler:
case 2: // change items
var itemNumber = InputNumber("Please enter an item ID");
var index = ItemIndex(itemNumber);
if (index == -1)
{
Console.WriteLine($"Item {itemNumber} not found.");
}
else
{
var newItem = InputItemData();
newItem.ItemNumber = itemNumber;
items[index] = newItem;
}
break;
For bonus points you can actually provide the current values to the InputItemData method so the user can re-use them instead of just asking for a complete new record each time.

C# Converting an array to a list

I am working on an assignment that deals with file input and output. The instructions are as follows:
Write a program to update an inventory file. Each line of the inventory file will have a product number, a product name and a quantity separated by vertical bars. The transaction file will contain a product number and a change amount, which may be positive for an increase or negative for a decrease. Use the transaction file to update the inventory file, writing a new inventory file with the update quantities. I have provided 2 Input files to test your program with as well as a sample output file so you see what it should look like when you are done.
Hints:
This program requires 3 files
Initial Inventory File
File showing updates to be made
New Inventory File with changes completed
Use Lists to capture the data so you don’t have to worry about the number of items in the files
Each line of the Inventory file looks something like this:
123 | television | 17
I have also been given the basic structure and outline of the program:
class Program
{
public class InventoryNode
{
// Create variables to hold the 3 elements of each item that you will read from the file
// Make them all public
public InventoryNode()
{
// Create a constructor that sets all 3 of the items to default values
}
public InventoryNode(int ID, string InvName, int Number)
{
// Create a constructor that sets all 3 of the items to values that are passed in
}
public override string ToString() // This one is a freebie
{
return IDNumber + " | " + Name + " | " + Quantity;
}
}
static void Main(String[] args)
{
// Create variables to hold the 3 elements of each item that you will read from the file
// Create variables for all 3 files (2 for READ, 1 for WRITE)
List<InventoryNode> Inventory = new List<InventoryNode>();
InventoryNode Item = null;
// Create any other variables that you need to complete the work
// Check for proper number of arguments
// If there are not enough arguments, give an error message and return from the program
// Otherwise
// Open Output File
// Open Inventory File (monitor for exceptions)
// Open Update File (monitor for exceptions)
// Read contents of Inventory into the Inventory List
// Read each item from the Update File and process the data
// Write output file
//Close all files
return;
}
}
There is a lot of steps to this problem but right now I am only really concerned with how to read the inventory file into a list. I have read files into arrays before, so I thought I could do that and then convert the array to a list. But I am not entirely sure how to do that. Below is what I have created to add to the main method of the structure above.
int ID;
string InvName;
int Number;
string line;
List<InventoryNode> Inventory = new List<InventoryNode>();
InventoryNode Item = null;
StreamReader f1 = new StreamReader(args[0]);
StreamReader f2 = new StreamReader(args[1]);
StreamWriter p = new StreamWriter(args[2]);
// Read each item from the Update File and process the data
while ((line = f1.ReadLine()) != null)
{
string[] currentLine = line.Split('|');
{
ID = Convert.ToInt16(currentLine[0]);
InvName = currentLine[1];
Number = Convert.ToInt16(currentLine[2]);
}
}
I am a bit hung up on the Inventory Node Item = null; line. I am not really sure what this is supposed to be doing. I really just want to read the file to an array so I can parse it and then pass that data to a list. Is there a way to do that that is something similar to the block I have written? Maybe there is a simpler way. I am open to that, but I figured I'd show my train of thought.
There is not need to add everything to an array and then convert it to the list. InventoryNode Item = null is there to represent a line from the file.
You're pretty close. You just need to instantiate the InventoryNode and feed it the results of the split() method.
You're almost there. You already have fetched ID, InvName and Number, so you just have to instantiate the InventoryNode:
Item = new InventoryNode(...);
And then add Item to your list.
Note that Inventory Node Item = null; is not doing much; it just declares a variable that you can use later. This wasn't strictly necessary as the variable could have been declared inside the loop instead.

C# Split text array into sub array

I can't seem to find much on this online :(
For my course I have to get text from a grocery.txt file and output an invoice.
The text file looks like this:
regular,bread,2.00,2
regular,milk,2.00,3
regular,cereal,4.00,1
fresh,rump steak,11.99,0.8
fresh,apple,4.60,1.00
fresh,cucumber,2.20,0.936
regular,cream,2.20,1
regular,mustard,3.30,1
fresh,carrots,1.79,1.5
regular,tomato sauce,2.95,1
regular,salt,2.80,1
fresh,bananas,4.00,1.2
Currently I use this method to get the text:
string[] groceryItemsArray = System.IO.File.ReadAllLines(#"C:\C\groceries.txt");
What I get is an array that in stores the entire line (for example "fresh,bananas,4.00,1.2").
I have no idea how to split the array into sub arrays or even whats the best way to go about this. Unfortunately this course task are way too advanced for the little material we have been taught and time we have for this. I have already spend around 6 hours watching videos and getting not very far in learning the advanced stuff.
This is what I am trying to accomplish.
A. Class named grocerrItem. This class has properties:
name and price
this class must have 2 constructors
A. subclass of this is a purchasedItem.
this class has an integer property 'quantity'
one of its methods findCost, calculates the cost of the item, including 10% GST.
the formula for this is price * quantity * 1.1
C. A subclass of this class (purchasedItem), freshItem has
a property weight, a double type.
The findCost method here, uses the formula:wieght * price, as it is not subject to GST.
Groceries.txt contains information as follows:
type(regular or fresh), name, price, quantity/weight - depending on being regular or fresh.
** An invoice should be represented as a collection of grocery items (parent class). This can be done using any container structure i.e. array, list or collection. you will then use iteration
You can just use String.Split which returns you the sub array that you want.
public static void Main()
{
string[] groceryItemsArray = System.IO.File.ReadAllLines(#"C:\C\groceries.txt");
// now split each line content with comma. It'll return you an array (sub-array)
foreach (var line in groceryItemsArray)
{
string[] itemsInLine = line.Split(',');
// Do whatevery you want to do with this.
// e.g. for 1st line itemsInLine array will contains 4 items
// "regular","bread","2.00", "2"
}
}
You can use this code (I'm not sure what exactly you looking for):
/// It's return all text as a single list
var groceryItemsArray = System.IO.File.ReadAllLines(#"C:\C\groceries.txt")
.SelectMany(x => x.Split(new char[]{','} , StringSplitOptions.RemoveEmptyEntries)).ToList() ;
Or if want to return as Child List can use this code:
var groceryItemsArray = System.IO.File.ReadAllLines(#"C:\C\groceries.txt").Select(x =>
new { Child = x.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries) }).ToList();
I didn't really understand what are you trying to output, but here's some basic things I did understand on your question:
(code not tested)
I created a parent class:
class GroceryItem
{
public string ItemName {get;set;}
public decimal Price {get;set;}
public GroceryItem() { }
}
And creates a child class:
class PurchasedItem : GroceryItem
{
public int Quantity { get;set; }
public decimal Cost { get;set; }
public PurchasedItem(string[] item)
{
ItemName = item[1];
Price = decimal.Parse(item[2]);
Quantity = int.Parse(item[3]);
FindCost();
}
private void FindCost()
{
Cost = Price * Quantity * 1.1;
}
}
Using your input to get all groceryItems, you can iterate using foreach loop and collect a list of purchasedItems.
Main()
{
string[] groceryItems = System.IO.File.ReadAllLines(#"C:\C\groceries.txt");
var purchasedItems = new List<PurchasedItem>();
foreach (var item in groceryItems)
{
string[] line = item.Split(',');
purchasedItems.Add(new PurchasedItem(line));
}
}
Well if you didn't understand this basic concept of programming, you better start on this link.

How do I generate a List<T> in the step definition of a SpecFlow Scenario?

In the documentation for SpecFlow Step Definitions it shows an example where you can create a list in the step definition by using a comma separated list in the scenario:
For example:
Given I am available on "Tuesday,Friday,Sunday"
would result in:
#Given("I am available on \"(.+)\"")
public void I_have_cukes_in_my_belly(List<String> days) {
// Do something with the days
}
Unfortunately, when I do it, I get this:
#Given("I am available on ""(.*)"")
public void I_have_cukes_in_my_belly(string days) {
// Do something with the days
}
I am using VS 2012 and version 1.9.1 of SpecFlow. Does anyone have any idea what I might be doing wrong? Or how I can go about fixing this?
Thanks in advance.
You could do something like:
Given I am available on these days:
| DaysOfWeek |
| Monday |
| Tuesday |
| Wednesday |
Then you could use the table and convert that to a list...
#Given("I am available on these days:")
public void I_have_cukes_in_my_belly(Table table) {
List<string> days = new List<string>();
foreach (var tableRow in table.Rows)
{
days.Add(tableRow["DaysOfWeek"]);
}
}
The only language that seems to support Lists currently is Java. I'm assuming you're using C# as you're using VS2012. If you switch the code sample on your linked page to C# instead of Java, the List example goes away and I'm seeing the same behavior you are.
However, you can simply get the string as a parameter and put it into a List. 1 line.
C#
[Given(#"I am available on ""(.*)""")]
public void GivenIAmAvailableOn(string days)
{
List<String> daysList = new List<string>(days.Split(','));
You could try querying the Table instance to get the list you are looking for.
expectedTable.Rows.Select(row => row.Values.FirstOrDefault()).ToList()
If you click C# on the Step Definitions page you will see that the List examples disappear. However as OCary points out you can simulate it by splitting the string.
But I would suggest that there is no need to cast back to list and you can just use IEnumerable via Linq instead so you can parse the list more simply i.e.
[Given(#"I am available on ""(.*)""")]
public void GivenIAmAvailableOn(string days)
{
var daysList = from x in days.Split(',') select x.Trim();
Currently I'm using a step argument transformation to get the list right:
[StepArgumentTransformation(#"((?:.*)(?:,.*)*)")]
public List<string> StringToList(string list)
{
// (
// (?: - Don't capture
.* - Match any character
// )
// (?: - Don't capture
// , - Separated by a comma
// .* - Match any character
// )* - Zero or more items after the first item
// )
return list
.Split(',')
.Select(x => x.Trim())
.ToList();
}
Then you'd be able to use List<string> as the argument type, like so:
[Given(#"I am available on ""(.*)""")]
public void GivenIAmAvailableOn(List<string> days)
{
}
Use Table to IEnumerable<T> convertor:
[StepArgumentTransformation]
public static IEnumerable<string> ToStringEnumerable(Table table) =>
table.Rows.Select(t => t.Values.Single());
Then you can use it as in your example (or cast to List<T> if you like):
#Given("I am available on \"(.+)\"")
public void I_have_cukes_in_my_belly(IEnumerable<String> days) {
// Do something with the days
}

Search algorithm required

I need a c# program ( search algorithm ), ie, When user types a character, the display should update to show all valid choices for the next character and a list of possible matching stations.
Ex: User Input: D A R T, it should display
DARTFORD and DARTMOUTH
Suggested outline is below:
public class Suggestions
{
HashSet<Character> nextLetters { get; set; }
HashSet<String> stations { get; set; }
}
public class StationFinder
{
private static String[] stations = new String[] {"LIVERPOOL LIME STREET", "BIRMINGHAM
NEW STREET", "KINGSTON", " DARTFORD", "DARTMOUTH" };
public Suggestions GetSuggestions( String userInput )
{
// TODO Compute result
Suggestions result = new Suggestions();
return result;
}
}
This is just a suggestion it can be modified as well.
Regards,
Vishnu
I do not know C# personally so I can't help you with the code but what you want to use is called a TRIE. This is a specific type of tree structure for strings. The nice property is you can very see all legal endings given the starting of a string. This is perfect for things like auto suggest etc. and I think is what you want for you thing. just google around for TRIE implementations in C#
What you want is a Ternary search tree look here wikipedia and here c# example

Categories

Resources