How to transfer ifelse code segment by OOP? - oop

I know that I should break down the method by condition, and implement interface to each subclass, but I do not know how does the client class use it, can you give me simple sample?
public void buildInfoItemUpdater() {
for (int i = 0; i < this.projectInfoInputItemUpdaters.size(); i++) {
if (this.projectInfoInputItemUpdaters.get(i) instanceof ComboBoxUpdater) {
ComboBoxUpdater tempItem = (ComboBoxUpdater) this.projectInfoInputItemUpdaters.get(i);
projectInfoInputItemUpdaters.get(i).setAnswer(tempItem.getUserAnswer());
} else if (this.projectInfoInputItemUpdaters.get(i) instanceof TextBoxUpdater) {
TextBoxUpdater tempItem = (TextBoxUpdater) this.projectInfoInputItemUpdaters.get(i);
projectInfoInputItemUpdaters.get(i).setAnswer(tempItem.getUserAnswer());
} else if (this.projectInfoInputItemUpdaters.get(i) instanceof TextFieldUpdater) {
TextFieldUpdater tempItem = (TextFieldUpdater) this.projectInfoInputItemUpdaters.get(i);
projectInfoInputItemUpdaters.get(i).setAnswer(tempItem.getUserAnswer());
}
}
}
Thank you in advance.

As suggested by #SirPentor, if the Updater classes have a common base class (lets call it UpdaterBase), then define the getUserAnswer() method there, most likely as abstract.
Then you could simplify buildInfoItemUpdater() as follows:
public void buildInfoItemUpdater() {
for (int i = 0; i < this.projectInfoInputItemUpdaters.size(); i++) {
UpdaterBase tempItem =
(UpdaterBase) this.projectInfoInputItemUpdaters.get(i);
projectInfoInputItemUpdaters.get(i).setAnswer(tempItem.getUserAnswer());
}
}
Additionally, whats the difference between this.projectInfoInputItemUpdaters.get(i) and projectInfoInputItemUpdaters.get(i)? Seems like your calling get() twice on the same object, right? You may be able to simplify this part as well.

Related

How to find if items in 2 list match (but can't use direct equality)

I have this code here, to see if the items in both lists are identical:
for (final car in this.cars) {
bool found = false;
for (final car2 in garage2.cars) {
if (car2.id == car.id) {
found = true;
break;
}
}
if (!found) {
return false;
}
}
return true;
}
(I previously check if the 2 list lengths are equal). Is there a way to rewrite that so that I don't have O(n2) complexity?
As an option you can override quals and hashcode methods for class Car
something like this
class Car {
int id;
// other fields
#override
bool operator ==(Object o) => o is Car && id == o.id;
#override
int get hashCode => id.hashCode;
}
and then you can use the native method listEquals, which compares for deep equality.
import 'package:flutter/foundation.dart';
bool isEqual = listEquals<Car>(cars, garage2.cars);

add a object to a array in my class

I want to add an object (from a different class) to an array in my class.
When I try to do that I get this
error: 0xC0000005: Access violation writing location
0x0000000000000000
I create the object (to be added) in the main function and I use the push method in the main function to add this object to my Parking_Lot class.
My code:
void Parking_Lot::push(Cars const &car)
{
time_t t = time(NULL);
struct tm Today = *localtime(&t);
if (is_full())
{
printf("Parking lot is full!!\n");
return;
}
if (Today.tm_hour < OpeningT.tm_hour && Today.tm_hour > ClosingT.tm_hour)
{
printf("Parking lot is now closed!!\n");
printf("Opening time: from %02d:%02d to %02d:%02d\n", OpeningT.tm_hour, OpeningT.tm_min, ClosingT.tm_hour, ClosingT.tm_min);
}
else if (Today.tm_hour == OpeningT.tm_hour || Today.tm_hour == ClosingT.tm_hour)
{
if(Today.tm_min > OpeningT.tm_min || Today.tm_min < ClosingT.tm_min) Lot[front++] = car;
else
{
printf("Parking lot is now closed!!\n");
printf("Opening time: from %02d:%02d to %02d:%02d\n", OpeningT.tm_hour, OpeningT.tm_min, ClosingT.tm_hour, ClosingT.tm_min);
}
}
else if(Today.tm_hour > OpeningT.tm_hour && Today.tm_hour < ClosingT.tm_hour) Lot[front++] = car;
}
where the car is the object I want to add and the Lot is the array in my class that I want to add the object to.
The constructor of my class:
Parking_Lot::Parking_Lot(int s)
{
Cars* Lot = new Cars[s+1];
size = s;
front = 0;
}
What am i doing wrong here and how can I fix it?
The problem is in your constructor:
Parking_Lot::Parking_Lot(int s)
{
Cars* Lot = new Cars[s+1];
size = s;
front = 0;
}
You define a new and separate variable Lot inside the constructor. It will not be related to any possible member variable you might have with the same name.
You need to initialize the member variable instead:
Parking_Lot::Parking_Lot(int s)
{
Lot = new Cars[s+1];
size = s;
front = 0;
}

Cannot update UI with Invoke() and BeginInvoke() in C#

My main process:
public void quoteStartReceive()
{
Thread thdWrite = new Thread(new ThreadStart(DoParseGUIDisplay));
thdWrite.IsBackground = true;
thdWrite.Start();
}
My thread function:
void DoParseGUIDisplay()
{
for (int i = 0; i < 1024; i++)
{
if (myQueue.Count > 0)
{
string strOut = myQueue.Dequeue().ToString();
Tick tick = new Tick(strOut);
if (tick.m_last != "")
{
string msg = "Update Text";
if (this.textBox1.InvokeRequired)
{
this.textBox1.BeginInvoke((MethosInvoker)delegate () {this.textBox1.Text = msg; };
}
else
{
this.textBox1.Text = msg;
}
}
}
}
}
No matter I tried to use Invoke() or BeginInvoke(), I cannot update the text in textBox1.
I also tried another way:
public delegate void UpdateTextCallback(string text);
It still cannot help me to update my textBox1.
Help me to find out what stuff I missed. Thanks.
put an argument before the thread:
Application.DoEvents();
and it should be put after the m_last was updated.

Roslyn - replace node and fix the whitespaces

In my program I use Roslyn and I need to replace a node with a new node. For example, if I have code like
public void Foo()
{
for(var i = 0; i < 5; i++)
Console.WriteLine("");
}
and I want to insert brackes for for statement, I get
public void Foo()
{
for(var i = 0; i < 5; i++)
{
Console.WriteLine("");
}
}
I tried to use NormalizeWhitespace, but if I use it on for statement, I get
public void Foo()
{
for(var i = 0; i < 5; i++)
{
Console.WriteLine("");
}
}
However, I'd like to have for statement formatted correctly. Any hints how to do it?
EDIT:
I solved it by using:
var blockSyntax = SyntaxFactory.Block(
SyntaxFactory.Token(SyntaxKind.OpenBraceToken).WithLeadingTrivia(forStatementSyntax.GetLeadingTrivia()).WithTrailingTrivia(forStatementSyntax.GetTrailingTrivia()),
syntaxNodes,
SyntaxFactory.Token(SyntaxKind.CloseBraceToken).WithLeadingTrivia(forStatementSyntax.GetLeadingTrivia()).WithTrailingTrivia(forStatementSyntax.GetTrailingTrivia())
);
However, the answer from Sam is also correct.
You need to use .WithAdditionalAnnotations(Formatter.Annotation), but only on the specific element you want to format. Here's an example from the NullParameterCheckRefactoring project.
IfStatementSyntax nullCheckIfStatement = SyntaxFactory.IfStatement(
SyntaxFactory.Token(SyntaxKind.IfKeyword),
SyntaxFactory.Token(SyntaxKind.OpenParenToken),
binaryExpression,
SyntaxFactory.Token(SyntaxKind.CloseParenToken),
syntaxBlock, null).WithAdditionalAnnotations(Formatter.Annotation, Simplifier.Annotation);

How to write a custom FindElement routine in Selenium?

I'm trying to figure out how to write a custom FindElement routine in Selenium 2.0 WebDriver. The idea would be something like this:
driver.FindElement(By.Method( (ISearchContext) => {
/* examine search context logic here... */ }));
The anonymous method would examine the ISearchContext and return True if it matches; False otherwise.
I'm digging through the Selenium code, and getting a bit lost. It looks like the actual By.* logic is carried out server-side, not client side. That seems to be complicating matters.
Any suggestions?
I do a multi-staged search. I have a method that performs a try catch and then a method that gets the element. In theory you could do a try catch until instead of this way but I like this way better because of my setup.
public bool CheckUntil(IWebDriver driver, string selectorType, string selectorInfo)
{
int Timer = 160;
bool itemFound = false;
for (int i = 0; i < Timer; i++)
if(itemFound)
{
i = 0
}
else
{
Thread.Sleep(500);
if(selectorType.ToLower() == "id" && TryCatch(driver, selectorType, selectorInfo))
{
if(driver.FindElement(By.Id(selectorInfo).Displayed)
{
itemFound = true;
}
}
else if(selectorType.ToLower() == "tagname" && TryCatch(driver, selectorType, selectorInfo))
{
if(driver.FindElement(By.TagName(selectorInfo).Displayed)
{
itemFound = true;
}
}
}
return itemFound;
}
Here's my try catch method you can add as many different types as you want id, cssselector, xpath, tagname, classname, etc.
public bool TryCatch(IWebDriver driver, string selectorType, string selectorInfo)
{
bool ElementFound = false;
try
{
switch(selectorType)
{
case "id":
driver.FindElement(By.Id(selectorInfo);
break;
case "tagname":
driver.FindElement(By.TagName(selectorInfo);
break;
}
ElementFound = truel
}
catch
{
ElementFound = false;
}
return ElementFound;
}
Ok, I figured out how to do this. I'm leveraging driver.ExecuteScript() to run custom js on the webdriver. It looks a bit like this:
function elementFound(elem) {
var nodeType = navigator.appName == ""Microsoft Internet
Explorer"" ? document.ELEMENT_NODE : Node.ELEMENT_NODE;
if(elem.nodeType == nodeType)
{
/* Element identification logic here */
}
else { return false; }
}
function traverseElement(elem) {
if (elementFound(elem) == true) {
return elem;
}
else {
for (var i = 0; i < elem.childNodes.length; i++) {
var ret = traverseElement(elem.childNodes[i]);
if(ret != null) { return ret; }
}
}
}
return traverseElement(document);