Using scanner to read phrases - parsing

Hey StackOverflow Community,
So, I have this line of information from a txt file that I need to parse.
Here is an example lines:
-> date & time AC Power Insolation Temperature Wind Speed
-> mm/dd/yyyy hh:mm.ss kw W/m^2 deg F mph
Using a scanner.nextLine() gives me a String with a whole line in it, and then I pass this off into StringTokenizer, which then separates them into individual Strings using whitespace as a separator.
so for the first line it would break up into:
date
&
time
AC
Power
Insolation
etc...
I need things like "date & time" together, and "AC Power" together. Is there anyway I can specify this using a method already defined in StringTokenizer or Scanner? Or would I have to develop my own algorithm to do this?
Would you guys suggest I use some other form of parsing lines instead of Scanner? Or, is Scanner sufficient enough for my needs?
ejay

oh, this one was tricky, maybe you could build up some Trie structure with your tokens, i was bored and wrote a little class which solves your problem. Warning: it's a bit hacky, but was fun to implement.
The Trie class:
class Trie extends HashMap<String, Trie> {
private static final long serialVersionUID = 1L;
boolean end = false;
public void addToken(String strings) {
addToken(strings.split("\\s+"), 0);
}
private void addToken(String[] strings, int begin) {
if (begin == strings.length) {
end = true;
return;
}
String key = strings[begin];
Trie t = get(key);
if (t == null) {
t = new Trie();
put(key, t);
}
t.addToken(strings, begin + 1);
}
public List<String> tokenize(String data) {
String[] split = data.split("\\s+");
List<String> tokens = new ArrayList<String>();
int pos = 0;
while (pos < split.length) {
int tokenLength = getToken(split, pos, 0);
tokens.add(glue(split, pos, tokenLength));
pos += tokenLength;
}
return tokens;
}
public String glue(String[] parts, int pos, int length) {
StringBuilder sb = new StringBuilder();
sb.append(parts[pos]);
for (int i = pos + 1; i < pos + length; i++) {
sb.append(" ");
sb.append(parts[i]);
}
return sb.toString();
}
private int getToken(String[] tokens, int begin, int length) {
if (end) {
return length;
}
if (begin == tokens.length) {
return 1;
}
String key = tokens[begin];
Trie t = get(key);
if (t != null) {
return t.getToken(tokens, begin + 1, length + 1);
}
return 1;
}
}
and how to use it:
Trie t = new Trie();
t.addToken("AC Power");
t.addToken("date & time");
t.addToken("date & foo");
t.addToken("Speed & fun");
String data = "date & time AC Power Insolation Temperature Wind Speed";
List<String> tokens = t.tokenize(data);
for (String s : tokens) {
System.out.println(s);
}

Related

Stream Data Calculation In Flux

The following code illustrates a logic I need in a Spring Reactive project:
Inputs:
var period = 3;
int [] inArr = {2, 4, 6, 7, 9, 11, 13, 16, 17, 18, 20, 22 };
Calculation:
var upbond = inArr[0] + period;
var count =0;
List<Integer> result = new ArrayList();
for(int a: inArr){
if(a <= upbond){
count++;
}else{
result.add(count);
count = 1;
upbond += period;
}
}
result.add(count);
System.out.println(Arrays.toString(result.toArray()));
The data source of the sorted integers is the Flux from DB where it shall continually fetch data once a new suitable data is written into the DB. And the result shall be a stream that is sending out to another node through RSocket (by the request-stream communication mode).
After some online searching on Reactor, including some tutorials, I still can't figure out how to write the logic in the Flux fashion. The difficulty I have is that those calculations on data defined outside of the loop.
How shall I approach it in the Reactor?
The scan() variant that lets you use a separately typed accumulator is your friend here.
I'd approach this with a separate State class:
public class State {
private int count;
private Optional<Integer> upbond;
private Optional<Integer> result;
public State() {
this.count = 0;
this.upbond = Optional.empty();
this.result = Optional.empty();
}
public State(int count, int upbond) {
this.count = count;
this.upbond = Optional.of(upbond);
this.result = Optional.empty();
}
public State(int count, int upbond, int result) {
this.count = count;
this.upbond = Optional.of(upbond);
this.result = Optional.of(result);
}
public int getCount() {
return count;
}
public Optional<Integer> getUpbond() {
return upbond;
}
public Optional<Integer> getResult() {
return result;
}
}
...and then use scan() to build up the state element by element:
sourceFlux
.concatWithValues(0)
.scan(new State(), (state, a) ->
a <= state.getUpbond().orElse(a + period) ?
new State(state.getCount() + 1, state.getUpbond().orElse(a + period)) :
new State(1, state.getUpbond().orElse(a + period) + period, state.getCount())
)
.windowUntil(s -> s.getResult().isPresent())
.flatMap(f -> f.reduce((s1, s2) -> s1.getResult().isPresent()?s1:s2).map(s -> s.getResult().orElse(s.getCount() - 1)))
Aside: The concatWithValues() / windowUntil() / flatMap() bits are there to handle the last element - there's probably a cleaner way of achieving that, if I think of it I'll edit the answer.
I think scan is definitely the right tool here, combined with a stateful class, although my approach would be slightly different than Michaels.
Accumulator:
class UpbondAccumulator{
final Integer period;
Integer upbond;
Integer count;
Boolean first;
Queue<Integer> results;
UpbondAccumulator(Integer period){
this.period = period;
this.count = 0;
this.upbond = 0;
this.results = new ConcurrentLinkedQueue<>();
this.first = true;
}
//Logic is inside accumulator, since accumulator is the only the only thing
//that needs it. Allows reuse of accumulator w/o code repetition
public UpbondAccumulator process(Integer in){
//If impossible value
//Add current count to queue and return
//You will have to determine what is impossible
//Since we concat this value on the end of flux
//It will signify the end of processing
//And emit the last count
if(in<0){
results.add(count);
return this;
}
//If first value
//Do stuff outside loop
if(this.first) {
upbond = in + period;
first=false;
}
//Same as your loop
if(in <= upbond)
count++;
else {
results.add(count);
count = 1;
upbond += period;
}
//Return accumulator
//This could be put elsewhere since it isn't
//Immediately obvious that `process` should return
//the object but is simpler for example
return this;
}
public Mono<Integer> getResult() {
//Return mono empty if queue is empty
//Otherwise return queued result
return Mono.justOrEmpty(results.poll());
}
}
Usage:
dbFlux
//Concat with impossible value
.concatWithValues(-1)
//Create accumulator, process value and return
.scan(new UpbondAccumulator(period), UpbondAccumulator::process)
//Get results, note if there are no results, this will be empty
//meaning it isn't passed on in chain
.flatMap(UpbondAccumulator::getResult)
Following comment from Michael here is an immutable approach
Accumulator:
public class UpbondAccumulator{
public static UpbondState process(int period,Integer in,UpbondState previous){
Integer upbond = previous.getUpbond().orElse(in + period);
int count = previous.getCount();
if(in<0) return new UpbondState(upbond, count, count);
if(in <= upbond) return new UpbondState(upbond,count + 1 , null);
return new UpbondState(upbond + period, 1, count);
}
}
State object:
public class UpbondState {
private final Integer upbond;
private final int count;
private final Integer result;
public UpbondState() {
this.count = 0;
this.upbond = null;
this.result = null;
}
public UpbondState(Integer upbond, int count,Integer result) {
this.upbond = upbond;
this.count = count;
this.result = result;
}
public int getCount() { return count; }
public Optional<Integer> getUpbond() { return Optional.ofNullable(upbond); }
public Integer getResult() { return result; }
public boolean hasResult() { return result!=null; }
}
Usage:
dbFlux
.concatWithValues(-1)
.scan(new UpbondState(),
(prev, in) -> UpbondAccumulator.process(period,in,prev))
//Could be switched for Optional, but would mean one more map
//+ I personally think makes logic less clear in this scenario
.filter(UpbondState::hasResult)
.map(UpbondState::getResult)

Fibonacci sequence, public static void xxx

I'm just a very beginner and need for help with Fibonacci sequence. So the problem is that I need to ask a number from the answerer and secondly print the Fibonacci number that fits with the answerer's number? Is the method that I need to use "public static void xxx" loop?
I hope someone understands my bad English and can help me with my problem.
I hope you need it in java:
import java.io.*;
public class Fibonacci{
// your method public static void xxx
public static void fib() throws IOException
{
// take input from user
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
// compute nth fibonacci: your loop
int f1 = 0, f2 = 1;
if(n == 0)
System.out.println(f1);
for(int i=2; i<n; i++)
{
int fi = f1 + f2;
f1 = f2;
f2 = fi;
}
// print your answer
System.out.println(f2);
}
public static void main(Strings args[])
{
// call fib method
fib();
}
}

Repast Java: scheduling agent and global behaviors in a structural way

I am previously working with Netlogo for years and I am very much getting used to developing the agent-based model based on a set of procedures. An example of supply chain simulation model structure looks like below:
;;the main simulation loop
#ScheduledMethod(start = 1, interval = 1)
public void step() {
place-order-to-suppliers() ;;procedures involving customer agent behaviors (a number of methods)
receive-shipment-from-suppliers() ;;procedures involving both supplier and customer agents and their behaviors (methods)
receive-order-from-customers() ;;procedures involving supplier agent only
ship-order-to-customers() ;;procedures involving supplier agent only
summarize() ;;procedures involving global summary behaviors independent of any agents, as well as local summary behaviors per each type of agents (customer and supplier)
}
The above structure is very useful and intuitive to develop a simulation model. We first cut the simulation world into several key parts (procedures), within which we further develop specific methods related to associated agents and behaviors. The essential part is to establish a higher level procedure (like a package) which could be useful to integrate (pack) the different types of agents and their behaviors/interactions altogether in one place and execute the model in a desired sequential order based on these procedures.
Are there any hints/examples to implement such modular modelling strategy in Repast?
Update:
Below is a simple model I wrote which is about how boy and girl interacts in the party (the full reference can be found https://ccl.northwestern.edu/netlogo/models/Party). Below is the code for Boy Class (the girl is the same so not pasted again).
package party;
import java.util.ArrayList;
import java.util.List;
import repast.simphony.context.Context;
import repast.simphony.engine.environment.RunEnvironment;
import repast.simphony.engine.schedule.ScheduledMethod;
import repast.simphony.parameter.Parameters;
import repast.simphony.query.PropertyGreaterThan;
import repast.simphony.query.PropertyEquals;
import repast.simphony.query.Query;
import repast.simphony.random.RandomHelper;
import repast.simphony.space.continuous.ContinuousSpace;
import repast.simphony.space.grid.Grid;
import repast.simphony.space.grid.GridPoint;
import repast.simphony.util.ContextUtils;
public class Boy {
private ContinuousSpace<Object> space;
private Grid<Object> grid;
private boolean happy;
private int id, x, y,tolerance;
private boolean over;
Boy (Grid<Object> grid, int id, int x, int y) {
this.grid = grid;
this.id = id;
this.x = x;
this.y = y;
Parameters p = RunEnvironment.getInstance().getParameters();
int get_tolerance = (Integer) p.getValue("tolerance");
this.tolerance = get_tolerance;
}
// #ScheduledMethod(start = 1, interval = 1,shuffle=true)
// public void step() {
// relocation();
// update_happiness();
// endRun();
//
// }
public void endRun( ) {
Context<Object> context = ContextUtils.getContext(this);
Query<Object> query = new PropertyEquals<Object>(context, "happy", true);
int end_count = 0;
for (Object o : query.query()) {
if (o instanceof Boy) {
end_count ++;
}
if (o instanceof Girl) {
end_count ++;
}
}
if (end_count == 70) {
RunEnvironment.getInstance().endRun();
}
}
public void update_happiness() {
over = false;
Context<Object> context = ContextUtils.getContext(this);
Parameters p = RunEnvironment.getInstance().getParameters();
int tolerance = (Integer) p.getValue("tolerance");
GridPoint pt = grid.getLocation(this);
int my_x = this.getX();
int boy_count = 0;
int girl_count = 0;
Query<Object> query = new PropertyEquals<Object>(context, "x", my_x);
for (Object o : query.query()) {
if (o instanceof Boy) {
boy_count++;
}
else {
girl_count++;
}
}
int total = boy_count + girl_count;
double ratio = (girl_count / (double)total);
// System.out.println((girl_count / (double)total));
if (ratio <= (tolerance / (double)100)) {
happy = true;
// System.out.println("yes");
}
else {
happy = false;
// System.out.println("no");
}
over = true;
// System.out.println(over);
}
public void relocation() {
if (!happy) {
List<Integer> x_list = new ArrayList<Integer>();
for (int i = 5; i <= 50; i = i + 5) {
x_list.add(i);
}
int index = RandomHelper.nextIntFromTo(0, 9);
int group_x = x_list.get(index);
while(group_x == this.getX()){
index = RandomHelper.nextIntFromTo(0, 9);
group_x = x_list.get(index);
}
int group_y = 35;
while (grid.getObjectAt(group_x,group_y) != null) {
group_y = group_y + 1;
}
this.setX(group_x);
grid.moveTo(this, group_x,group_y);
}
}
public int getTolerance() {
return tolerance;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public int getID() {
return id;
}
public boolean getHappy() {
return happy;
}
public boolean getOver() {
return over;
}
public void setTolerance(int tolerance) {
this.tolerance = tolerance;
}
}
---------------------------------------------------------------------------------
The running of above code can follow the standard Repast Annotated scheduling method. However, since I want do some integration of the different agents and their methods altogether to allow the creation of bigger procedures(methods), I managed to create a Global Scheduler Agent Class to manage this modeling strategy. Below is the code:
package party;
import java.util.ArrayList;
import java.util.List;
import repast.simphony.context.Context;
import repast.simphony.engine.environment.RunEnvironment;
import repast.simphony.engine.schedule.ScheduleParameters;
import repast.simphony.engine.schedule.ScheduledMethod;
import repast.simphony.engine.schedule.Schedule;
import repast.simphony.query.PropertyEquals;
import repast.simphony.query.Query;
import repast.simphony.util.ContextUtils;
import repast.simphony.util.collections.IndexedIterable;
public class Global_Scheduler {
#ScheduledMethod(start = 1, interval = 1,shuffle=true)
public void updateHappiness() {
Context<Object> context = ContextUtils.getContext(this);
IndexedIterable<Object> boy_agents = context.getObjects(Boy.class);
IndexedIterable<Object> girl_agents = context.getObjects(Girl.class);
for (Object b: boy_agents) {
((Boy) b).update_happiness();
}
for (Object g: girl_agents) {
((Girl) g).update_happiness();
}
}
#ScheduledMethod(start = 1, interval = 1,shuffle=true)
public void relocate() {
Context<Object> context = ContextUtils.getContext(this);
IndexedIterable<Object> boy_agents = context.getObjects(Boy.class);
IndexedIterable<Object> girl_agents = context.getObjects(Girl.class);
for (Object b: boy_agents) {
((Boy) b).relocation();
}
for (Object g: girl_agents) {
((Girl) g).relocation();
}
}
#ScheduledMethod(start = 1, interval = 1,shuffle=true)
public void summary() {
Context<Object> context = ContextUtils.getContext(this);
Query<Object> query = new PropertyEquals<Object>(context, "happy", true);
int total_count = 0;
int boy_count = 0;
int girl_count = 0;
for (Object o : query.query()) {
if (o instanceof Boy) {
total_count ++;
boy_count++;
}
if (o instanceof Girl) {
total_count ++;
girl_count++;
}
}
System.out.println("Total happy person: " + total_count);
System.out.println("Total happy boys: " + boy_count);
System.out.println("Total happy girls: " + girl_count);
}
#ScheduledMethod(start = 1, interval = 1,shuffle=true)
public void endRun( ) {
Context<Object> context = ContextUtils.getContext(this);
Query<Object> query = new PropertyEquals<Object>(context, "happy", true);
int end_count = 0;
for (Object o : query.query()) {
if (o instanceof Boy) {
end_count ++;
}
if (o instanceof Girl) {
end_count ++;
}
}
if (end_count == 70) {
RunEnvironment.getInstance().endRun();
}
}
}
The above code using the global scheduler agent to run the model is working fine and the outcome should behave the same. However, I am not sure if the execution of the model really follows the sequence (i.e. update_happiness() -> relocate() -> summary() -> end_run(). I would also like to know if there are better and simpler way to achieve such modeling strategy?
The code example you provided will almost work exactly as-is in a repast model agent - you simply need to change the comment line prefix ;; to // and implement the methods place-order-to-suppliers(), etc in the agent class. The agent behavior structure in a typical ABM follows this exact structure. A general 'step' method that combines the various sub-steps according to the desired order of execution.
There are a number of behavior scheduling approaches outlined in the Repast FAQ: https://repast.github.io/docs/RepastReference/RepastReference.html#_scheduling . Scheduling via annotation as you've provided in the example will repeat the behavior on a regular interval, or at a single time step. You can also schedule dynamically in the model by directly putting an action on the Repast schedule. This type of scheduling is good for event-based behavior, like scheduling a one-time behavior that is triggered by some other event in the model. You can also schedule with #Watch annotations that trigger behaviors based on a set of conditions specified in the annotation.
You can use priorities in your #ScheduledMethod annotations, e.g.,
#ScheduledMethod(start = 1, interval = 1, shuffle=true, priority=1)
where a higher priority will run before a lower priority.

C# Textbox insert space for every 2 characters entered

Is there a way to insert a space for every 2 characters entered in a textbox?
For example as a user enters the string 22F188, i would like it to appear as 22 F1 88 in the textbox
[TestMethod]
public void StackOverflowQuestion()
{
var input = "0123457";
var temp = Regex.Replace(input, #"(.{2})", "$1 ");
Assert.AreEqual("01 23 45 7", temp);
}
Or
static string ProcessString(string input)
{
StringBuilder buffer = new StringBuilder(input.Length*3/2);
for (int i=0; i<input.Length; i++)
{
if ((i>0) & (i%2==0))
buffer.Append(" ");
buffer.Append(input[i]);
}
return buffer.ToString();
}
Add one space after every two characters and add a character infront of every single character
You can use keyPressed event for this.
int i = 0;
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if(i < 2){
i++;
}
else{
i = 0;
textBox1.Text += ' ';
}
}

How do I pretty-print productions and line numbers, using ANTLR4?

I'm trying to write a piece of code that will take an ANTLR4 parser and use it to generate ASTs for inputs similar to the ones given by the -tree option on grun (misc.TestRig). However, I'd additionally like for the output to include all the line number/offset information.
For example, instead of printing
(add (int 5) '+' (int 6))
I'd like to get
(add (int 5 [line 3, offset 6:7]) '+' (int 6 [line 3, offset 8:9]) [line 3, offset 5:10])
Or something similar.
There aren't a tremendous number of visitor examples for ANTLR4 yet, but I am pretty sure I can do most of this by copying the default implementation for toStringTree (used by grun). However, I do not see any information about the line numbers or offsets.
I expected to be able to write super simple code like this:
String visit(ParseTree t) {
return "(" + t.productionName + t.visitChildren() + t.lineNumber + ")";
}
but it doesn't seem to be this simple. I'm guessing I should be able to get line number information from the parser, but I haven't figured out how to do so. How can I grab this line number/offset information in my traversal?
To fill in the few blanks in the solution below, I used:
List<String> ruleNames = Arrays.asList(parser.getRuleNames());
parser.setBuildParseTree(true);
ParserRuleContext prc = parser.program();
ParseTree tree = prc;
to get the tree and the ruleNames. program is the name for the top production in my grammar.
The Trees.toStringTree method can be implemented using a ParseTreeListener. The following listener produces exactly the same output as Trees.toStringTree.
public class TreePrinterListener implements ParseTreeListener {
private final List<String> ruleNames;
private final StringBuilder builder = new StringBuilder();
public TreePrinterListener(Parser parser) {
this.ruleNames = Arrays.asList(parser.getRuleNames());
}
public TreePrinterListener(List<String> ruleNames) {
this.ruleNames = ruleNames;
}
#Override
public void visitTerminal(TerminalNode node) {
if (builder.length() > 0) {
builder.append(' ');
}
builder.append(Utils.escapeWhitespace(Trees.getNodeText(node, ruleNames), false));
}
#Override
public void visitErrorNode(ErrorNode node) {
if (builder.length() > 0) {
builder.append(' ');
}
builder.append(Utils.escapeWhitespace(Trees.getNodeText(node, ruleNames), false));
}
#Override
public void enterEveryRule(ParserRuleContext ctx) {
if (builder.length() > 0) {
builder.append(' ');
}
if (ctx.getChildCount() > 0) {
builder.append('(');
}
int ruleIndex = ctx.getRuleIndex();
String ruleName;
if (ruleIndex >= 0 && ruleIndex < ruleNames.size()) {
ruleName = ruleNames.get(ruleIndex);
}
else {
ruleName = Integer.toString(ruleIndex);
}
builder.append(ruleName);
}
#Override
public void exitEveryRule(ParserRuleContext ctx) {
if (ctx.getChildCount() > 0) {
builder.append(')');
}
}
#Override
public String toString() {
return builder.toString();
}
}
The class can be used as follows:
List<String> ruleNames = ...;
ParseTree tree = ...;
TreePrinterListener listener = new TreePrinterListener(ruleNames);
ParseTreeWalker.DEFAULT.walk(listener, tree);
String formatted = listener.toString();
The class can be modified to produce the information in your output by updating the exitEveryRule method:
#Override
public void exitEveryRule(ParserRuleContext ctx) {
if (ctx.getChildCount() > 0) {
Token positionToken = ctx.getStart();
if (positionToken != null) {
builder.append(" [line ");
builder.append(positionToken.getLine());
builder.append(", offset ");
builder.append(positionToken.getStartIndex());
builder.append(':');
builder.append(positionToken.getStopIndex());
builder.append("])");
}
else {
builder.append(')');
}
}
}

Resources