Determining the state of a process - java

I am creating a chatbot-like application and I need to know when the application has reached a certain state.
Currently I am using strings to find out what the topic of the conversation is.
Such as
String usersaid = text.toString();
if (usersaid.contains("topic-relevant word") {
execStateRelevantMethod();
}
However I'd like to know if there's a more reliable way to do this. Such as:
if (usersaid.contains("what time is it") {
state.set(timeQuery);
}
if (state == timeQuery) {
execStateRelevantMethod();
}
I have made those state commands up to show you what I'm meaning to ask.

Related

Angular Local Storage Delete Not Removing item

Hello I am learning angular and I'm working on a todo app that stores to local storage. Getting the local storage to remove a single item as well as editing an item has been a challenge and I've not found many good resources.
Right now it looks like its removing the entire array and I'm not sure why. Hopefully Ive included the proper details.
This is is my delete/remove in the CRUD task
deleteTask(task : Task) {
localStorage.removeItem(this.taskKey)
}
This is the delete task in the componant
deleteTask(idx: number) {
this.taskService.deleteTask(new Task(this.addTaskValue))
if( idx >= 0) {
this.taskArr.splice(idx, 1);
}
}
Other Details from the componant
taskArr: Task[];
public addTaskValue: string = '';
constructor(private taskService: TaskService) {}
ngOnInit(): void {
this.addTaskValue = '';
this.taskArr = this.taskService.getAllTasks();
}
Local Storage Image
I've tried to just use the splice out in the deleteTask but that only removed it from the screen and not the local storage. Ive tried a bunch of other things as well but cant recall them all in detail.
In the above code, you provided. I don't see a logic where the taskKey is even being set. I would add some console statements to see if you're even getting the right string in this.taskKey.
deleteTask(task : Task) {
console.log(this.taskKey); // check if this value is "tasks"
localStorage.removeItem(this.taskKey)
}
Essentially it needs to boil down to this.
localstorage.removeItem('tasks').

Handling additional data in Apache ServiceComb compensation methods

I'm currently looking at the implementations of saga pattern for distributed transactions and I found that Apache ServiceComp pack might be something that works for me.
However, I have found a problem that the limitation of compensating methods to have the same declaration as the methods they compensate may be a bottleneck.
From Apache's example:
#Compensable(compensationMethod = "cancel")
void order(CarBooking booking) {
booking.confirm();
bookings.put(booking.getId(), booking);
}
void cancel(CarBooking booking) {
Integer id = booking.getId();
if (bookings.containsKey(id)) {
bookings.get(id).cancel();
}
}
You can see that we have the same declaration for both methods.
But, what if I need additional information to compensate my transaction? For instance, I have a call to external system to update some flag to "true". When I need to compensate it, how do I make "cancel" method know what the original value of this flag was?
The things get more tricky when we update the whole object. How do I send the whole object before modification to the cancel transaction?
These limitation doesn't look quite promising. Do you know if there are approaches to fight with this limitation?
You can save localTxId and flag an in your application and use localTxId in the compensation method to get the flag
Map extmap = new HashMap();
#Autowired
OmegaContext omegaContext;
#Compensable(compensationMethod = "cancel")
void order(CarBooking booking) {
booking.confirm();
bookings.put(booking.getId(), booking);
//save flag
extmap.put(omegaContext.localTxId(),'Your flag')
}
void cancel(CarBooking booking) {
//get flag
extmap.get(omegaContext.localTxId());
Integer id = booking.getId();
if (bookings.containsKey(id)) {
bookings.get(id).cancel();
}
}

Observer pattern: notify with state

The examples I've seen on the internet only give notifyObservers() method to the Observable object. What if I want to also pass some data to the observers, so that they know if they should react to it or not? Does the observer pattern allow passing the data like maybe:
notifyObservers(Event e).
Or maybe the observers themselves should pull the change? Like maybe:
notifyObservers() -> call observer.update()
and then each observer decides if the new data is relevant for them, observable.getData(). However with this approach, it is unclear to me, how to get only the data that has changes, if it's at all needed.
Edit, example:
Say I want to make a taxi firm with operators, clients and taxi. As per #Pritam Banerjee's answer, I will say that taxi firm is a mediator between operators and clients (e.g. why - client can call for a taxi by phone, or online). Then my operators are subjects, and taxis are observers.
Operator ---observes---> TaxiFirm
TaxiFirm(waits for client) ---notifies one---> Operator (firm selects which operator is responsible, and passes a client to operator)
Taxi ---observes all---> Operators (need to somehow push data here, if the taxi is occupied, it can't accept new client)
Taxi ---notifies---> Operator (if taxi can accept a client it will notify operator about it, I am not concerned about any race conditions, because this event will be triggered manually. Also, maybe Taxi should notify the Firm and not operator?)
I think it's possible that TaxiFirm doesn't need to pass client to operator, but thinking about real life, it's really operators who speak to clients...
I've written down my thought process, please help me with figuring out the architecture for this model.
Of course the ObserverPattern allows you to pass information through its notify method. If a taxi needs the client info you can just pass:
observer.notify(ClientInfo info)
And of course the Observers could, instead, request the info:
observer.notify()
void notify() {
update();
}
Both are possible, but then, I would NOT say you really have the ObserverPattern here. According to this pattern, the Subject simply notifies all Observers. But what you described is that the Subject should notify one of the taxis, wait for its response (if the taxi is already carrying a passenger), and then possibly notify the next taxi. You could call that a variation of the ObserverPattern, but it's different.
A simple suggestion, for you to get started:
class Operator:
List<Taxi> taxis;
boolean chooseTaxi(RideNumber rideNumber) {
for (Taxi taxi : taxis) {
boolean isAccepted = taxi.notify(this, rideNumber);
if (isAccepted) {
markTaxiRideAsAccepted(taxi, rideNumber);
return true;
}
}
return false; // No taxi accepted the ride.
}
class Taxi:
boolean notify(Operator operator, RideNumber rideNumber) {
if (isTaxiAlreadyCarryingPassenger()) return false;
ClientInfo clientInfo = operator.getClientInfo(this, rideNumber);
startClientProcess(clientInfo);
return true;
}
Note: The RideNumber is just an identification number that the taxi later uses to request the client info from the operator. You could instead send the clientInfo through the notify method, but then all taxis would get this info, which is terrible for security, and could also be confusing (sending information which should not be used).
Update:
If this is a homework assignment, and you must use the exact ObserverPattern, you can do this:
class Operator:
List<Taxi> taxis;
void notifyAllTaxis(RideNumber rideNumber) {
for (Taxi taxi : taxis) {
taxi.notify(this, rideNumber);
}
}
}
ClientInfo getClientInfo(this, rideNumber) {
if (isRideNotYetAccepted(rideNumber)) {
markRideAsAccepted(taxi, rideNumber);
return getClientInfo(rideNumber);
}
else return null;
}
class Taxi:
void notify(Operator operator, RideNumber rideNumber) {
if (!isTaxiAlreadyCarryingPassenger()) {
ClientInfo clientInfo = operator.getClientInfo(this, rideNumber);
if (clientInfo != null) startClientProcess(clientInfo);
}
}
You can use Observer Design Pattern with Mediator Pattern so that the application can also subscribe and publish data to the other related applications.
For an example of this you can look over here.
For more details on Mediator Design Patterns you can read this article.

How to get all events in wikidata

I am using the wikidata toolkit and I want to get a list of all events.
I wrote a EntityDocumentProcessor, where I want to filter for the events out of my dump. Well I know that the event document has the id Q1190554 and that I have to somehow check if the instance of the current itemDocument is an "instance of" (P31) of an event.
#Override
public void processItemDocument(ItemDocument itemDocument) {
boolean isEvent = false;
for (StatementGroup statementGroup : itemDocument.getStatementGroups()) {
switch (statementGroup.getProperty().getId()) {
case "P31": // P31 is "instance of"
isEvent = containsValue(statementGroup, filterClass);
break;
case "P279": // P279 is "subclass of"
if (!isEvent) {
isEvent = containsValue(statementGroup, filterClass);
}
break;
}
}
}
private boolean containsValue(StatementGroup statementGroup, Value value) {
for (Statement s : statementGroup.getStatements()) {
if (value.equals(s.getValue())) {
return true;
}
}
return false;
}
This approach worked pretty good for getting people. But the problem with events is that events like WW2 (https://www.wikidata.org/wiki/Q362) dont have the event directly mapped. The event is somewhere hidden.
Does anyone knows a way how I can easily check if the current itemDocument is an event?
You should follow the hierarchy of the subclass of of the particular instance of to a split. So starting from Q362 you will eventually reach: https://www.wikidata.org/wiki/Q350604 - armed conflict, the presumption being that WWII is everything until prior to that split, namely:
1) world war: https://www.wikidata.org/wiki/Q103495 and
2) war: https://www.wikidata.org/wiki/Q198, then
3) armed conflict: https://www.wikidata.org/wiki/Q350604 which splits to:
1) conflict: https://www.wikidata.org/wiki/Q180684, which now splits to
2) event: https://www.wikidata.org/wiki/Q1190554
And since you are only interested in events, I will do this recursively until I reach the event class.

Java convention in practice - return mutliple values from method

I have two questions about Java Convention. I try to make use od Robert C. Martin's "Clean Code".
Following case:
public void startProgressIfAllowed() {
try {
tryStartProgressIfAllowed();
} catch (Exception exception) {
// log error
}
}
private void tryStartProgressIfAllowed() {
if (isStartProgressAllowed()) {
stopProgressOnCurrentlyStartedTask();
startProgressOnThisTask();
}
}
private boolean isStartProgressAllowed() {
// Calls JOptionPane.showConfirmDialog with JOptionPane.YES_NO_OPTION.
// Created dialog contains checkbox indicating that saving currently started task is required.
// returns boolean depending on JOptionPane.YES_NO_OPTION clicked button
}
private void stopProgressOnCurrentlyStartedTask() {
// Saves currently started task depending on checkbox selecion property and stops currently started.
// What is the correct way to get checkbox selecion property?
}
Proposed solution:
public void tryStartProgressIfAllowed() {
if (tryToStopProgressOnStartedTaskIfNecessary()) {
startProgressOnThisTask();
}
}
private boolean tryToStopProgressOnStartedTaskIfNecessary() {
// Calls JOptionPane.showConfirmDialog with JOptionPane.YES_NO_OPTION.
// Created dialog contains checkbox indicating that saving currently started task is required.
// Depending on checkbox selecion property saves task.
// returns boolean depending on JOptionPane.YES_NO_OPTION clicked button
}
But this approach doesn't meet the "Command Query Separation" principle, because tryToStopProgressOnStartedTaskIfNecessary(...) method performs some logic and returns success/failure value.
I think this approach also doesn't meet the "One level of abstraction per function" principle, because I suppose "check" and "save" operations are on different levels of abstraction.
Is the method name correct to avoid disinformation? Maybe better name would be tryToStopProgressAndSaveStartedTaskIfNecessary(...)?
Is there any better solution for above problem?
What about the following:
public void tryStartProgressOnThisTaskIfAllowed() {
tryStopTaskInProgressIfAllowed()
if (!isTaskInProgress()) {
tryStartProgressOnThisTask();
}
}
private void tryStopTaskInProgressIfAllowed() {
if (!isTaskInProgress()) {
return;
}
TaskInProgressResult result = whatToDoWithTaskInProgress();
if (result == Result.KEEP) {
return;
} else if (result == Result.DROP)
tryDropTaskInProgress();
} else if (result == Result.SAVE) {
trySaveTaskInProgress();
}
}
About your points:
You now have two separate methods for C and Q
I think the two things whatToDoWithTaskInProgress and tryDropTaskInProgress are the same level of abstraction. If you'd inline the code of one or the other you were absolutely right of course.
I changed some of the method names according to my taste :) The only thing I still don't like is the part "OnThisTask" because this task is somewhat meaningless. Maybe it's only because the rest of the code is unknown maybe OnNextTask or OnNewTask are better.
The problem we were having is that we were thinking in UI terms YES/NO + checkbox value. But it is much better to think in business terms here. I identified three different outcomes that are of interest: KEEP, SAVE, DROP How the answer is obtained should not matter to the calling method.
This seems something to ask on CodeReview, see the drop down at the top left of the page.
An example of how such stateliness is realized in Java SE: the regex Matcher class.
String s = ...
Pattern pattern = Pattern.compile("...");
Matcher m = pattern.matcher(s);
StringBuffer sb = new StringBuffer();
while (m.find()) {
m.appendReplacement(sb, ... m.group(1) ...);
}
m.appendTail(sb);
with m.matches() and m.lookingAt as alternative circuits too.
In short state is held in a processing class on the actual data (String here).

Categories

Resources