I have a .txt with content inserted in textBox1 and I already show the content to textBox2.
I want to move the part else { a = c; } to another textBox3 and delete this part in textBox2. How can I do it?
The content of text:
a = Calculation();
all = a;
if (a == 0)
{
a = b;
}
**else
{
a = c;
}**
all = b;
all = c;```
In modern programming, there is a tendency to separate the data (=model) from how this data is displayed (=view). This enables changing how you display the data without having to change the model. You can also change the model, without having to change the view.
For this separation, we need adapter code that couples the Model to the View: quite often called the ViewModel. The abbreviation for this idea is MVVM. Google this if you want to k know more about the theory behind this.
"I have a .txt with content"
First of all: you form is not interested where your data comes from, hide this in your model.
string GetText() {... // Read from file }
If later you decide that text should be read from a different source, for instance from a database, or from the internet, or maybe you decide that you ask the operator to type the text, the rest of your model and view won't have to change.
Besides: it will be easier to unit test this part.
"inserted in textBox1 and I already show the content to textBox2. I want to move the part else { a = c; } to another textBox3 and delete this part in textBox2"
I think you mean to say, that from the text that you fetched in GetText(), you want to show the "else" part (TODO: define the else part), in textBox3, and show the complete text without the "else" part in textBox2. The complete text should be "inserted" in textBox1.
So we need a method to separate your test into two: the "Else" part and the rest. Furthermore we need procedures to "Insert" the complete text, the "Else" text and the "Rest" text:
void InsertText (string text)
{
// not sure what "Insert" means. Do you mean replace?
// or add to the current cursor position?
this.textBox1.Text = ...
}
void ShowElsePart(string elseText)
{
this.textBox3.Text = elseText;
}
void ShowRest(string restText)
{
this.textBox2.Text = restText;
}
So I've hidden how I view "Else" part, the "Rest" part and what I mean with "Insert text". If later you decide you don't want to show it in a text Box, but for instance in a RichTextBox, or in a Listview, only one procedure needs to change.
We need to divide the text into the "Else" part and the "Rest".
You defined the "Else" part as the part else { a = c; }, so without the ** and more important: without new lines, or was this just the description, and could 'else { a = c; }be different text:else a = c;, or else { x = y; }or evenelse { while (x) {...}`?
This uncertainty is a good example of why you should separate the model from the view: if you decide to change your definition of the "Else" part, outsiders don't have to change.
void DivideText(string input, our string elsePart, out string rest)
{
// TODO implement
}
First we'll put it all together, then we'll do the implementation:
void DisplayInput()
{
string text = this.GetText();
this.InsertText(text);
this.DivideText(text, out string elseText, out string restText);
this.ShowElsePart(elseText);
this.ShowRest(restText);
}
Apart from that it is fairly easy to understand what happens, this code is highly reusable, easy to change and easy to text. If you want to read your text from a database, instead of plain text file, only one procedure needs to change. If you don't want to insert the text in textBox1, but in a file: only one place to change. If you define "Else" part differently: again only place to change.
Now about the "Else" part. According to your definition, "Else" is fairly simple:
const string elsePart = "else { a = c; }"
int elseStartIndex = text.IndexOf(elsePart, 0);
if (elseStartIndex < 0)
{
// elsePart not found
string restText = text;
}
else
{
string restText = text.Remove(elseStartIndex, elsePart.Length;
}
It could be that you meant something else with "Else" part: everything from the first else until the first }.
int indexStartElse = text.IndexOf("else", 0);
// TODO: what if no else?
int indexEndElse = text.IndexOf("}", indexStartElse);
// TODO: what if no }?
int elseTextLength = indexEndElse - indexStartElse;
string elseText = text.SubString(indexStartElse, elseTextLength);
string restText = text.Remove(indexStartElse, elseTextLength);
Related
// Language Selection
public static void SelectLanguage() {
waitForElementToBeClickable(driver.findElement(By.xpath("//div[#class=\"lang-identifier\"]")));
driver.findElement(By.xpath("//div[#class=\"lang-identifier\"]")).click();
List<WebElement> elements = driver.findElements(By.xpath("//ul[#class=\"dropdown-menu pull-right\"]/li"));
for (WebElement e : elements) {
String text = e.getAttribute("value");
System.out.println(e.getText());
if (text.equalsIgnoreCase("English")) {
e.click();
break;
} else if (e.getText().equalsIgnoreCase("Español")) {
e.click();
break;
} else if (e.getText().equalsIgnoreCase("Italiano")) {
e.click();
break;
} else if (e.getText().equalsIgnoreCase("Pусский")) {
e.click();
break;
} else if (e.getText().equalsIgnoreCase("Français")) {
e.click();
break;
} else if (e.getText().equalsIgnoreCase("Português")) {
e.click();
break;
} else {
System.out.println("Please select appropriate language");
}
}
}
I would suggest a much simpler but more flexible version of your method.
Some suggestions:
I would change your method to take the desired language as a parameter to significantly simplify the code but also make it very flexible.
WebDriverWait, in most cases, will return the found element(s). Use that to simplify your code to a one-liner, e.g.
new WebDriverWait(...).until(ExpectedConditions.elementToBeClickable).click();
You didn't provide the code of your custom method, waitForElementToBeClickable, but if you really want to keep it, have it return the element(s) waited for to make it more useful and save having to write extra code.
If you have nested double quotes, I would suggest you use a combination of double and single quotes. It's a personal preference but I think it makes it easier to read than \", e.g.
"//div[#class=\"lang-identifier\"]"
would turn into
"//div[#class='lang-identifier']"
Instead of grabbing all options and then looping through them to compare the contained text to some desired string, use an XPath that contains the desired text instead, e.g. for "English" the XPath will look like
//ul[#class='dropdown-menu pull-right']/li[text()='English']
NOTE: .getAttribute("value") gets the value of an INPUT and will not work on other elements, e.g. the LI elements in your elements variable. .getText() returns the text contained in an element but will not work on INPUTs.
After implementing these suggestions, the code turns into a two-liner and is very flexible.
public static void SelectLanguage(String language) {
new WebDriverWait(driver, Duration.ofSeconds(10)).until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.lang-identifier"))).click();
driver.findElement(By.xpath("//ul[#class='dropdown-menu pull-right']/li[text()='" + language + "']")).click();
}
I am trying to set up a search system for a database where each element (a code) in one table has tags mapped by a Many to many relationship. I am trying to write a controller, "search" where I can search a set of tags which basically act like key words, giving me an element list where the elements all have the specified tags. My current function is incredibly naive, basically it consists of retrieving all the codes which are mapped to be a tag, then adding those a set, then sorting the codes by how many times the tags for each code is found in the query string.
public List<Code> naiveSearch(String queryText) {
String[] tagMatchers = queryText.split(" ");
Set<Code> retained = new HashSet<>();
for (int i = 0; i < Math.min(tagMatchers.length, 4); i++) {
tagRepository.findAllByValueContaining(tagMatchers[i]).ifPresent((tags) -> {
tags.forEach(tag -> {
retained.addAll(tag.getCodes());
}
);
});
}
SortedMap<Integer, List<Code>> matches = new TreeMap<>();
List<Code> c;
for (Code code : retained) {
int sum = 0;
for (String tagMatcher : tagMatchers) {
for (Tag tag : code.getTags()) {
if (tag.getValue().contains(tagMatcher)) {
sum += 1;
}
}
}
c = matches.getOrDefault(sum, new ArrayList<>());
c.add(code);
matches.put(sum, c);
}
c = new ArrayList<>();
matches.values().forEach(c::addAll);
Collections.reverse(c);
return c;
}
This is quite slow and the overhead is unacceptable. My previous trick was a basically retrieval on the description for each code in the CRUDrepository
public interface CodeRepository extends CrudRepository<Code, Long> {
Optional<Code> findByCode(String codeId);
Optional<Iterable<Code>> findAllByDescriptionContaining(String query);
}
However this is brittle since the order of tags in containing factors into whether the result will be found. eg. I want "tall ... dog" == "dog ... tall"
So okay, I'm back several days later with how I actually solved this problem. I used hibernate's built in search library which has a very easy implementation in spring. Just paste the required maven coordinates in your POM.xml and it was ready to roll.
First I removed the manytomany for the tags<->codes and just concatenated all my tags into a string field. Next I added #Field to the tags field and then wrote a basic search Method. The method I wrote was a very simple search function which took a set of "key words" or tags then performed a boolean search based on fuzzy terms for the the indexed tags for each code. So far it is pretty good. My database is fairly small (100k) so I'm not sure about how this will scale, but currently each search returns in about 20-50 ms which is fast enough for my purposes.
I am attempting to add a search feature to Quill and want to highlight the text that it finds. I am having trouble getting the range index for the text it finds, and it is likely that I am not using the correct approach.
So far, I get the text using getContents() and can find matches by iterating through the lines. However, I have not been able to find the correct index position for setSelection(). A second issue is that I want the window to scroll to where the selection is found, and it is not scrolling into view.
...
myKeyPhrases = ['obvious', 'orange', 'apple'];
var myDelta = editor.getContents();
myDelta.eachLine((line, attributes, i) => {
mytext = line.filter((op) => typeof op.insert === 'string').map((op) => op.insert).join('');
mytext = mytext.toLowerCase();
ndx = isKeyPhraseFound(mytext, myKeyPhrases);
if (ndx >= 0){
// The code finds the matches OK to here.
// The next 4 lines don't get the correct range and scroll.
index = i;
editor.focus();
editor.setSelection(index, 1, Quill.sources.USER);
editor.scrollIntoView();
return index;
}
});
My desired results would be that a found text match would be selected and that the window would be scrolled so that the selection is displayed. The actual results are that the wrong text is selected and the window is not scrolled to view the selection.
You're basically there. I suspect your issue is that you're filtering out block elements, which acts similarly to Quill's getText method. According to the docs:
Non-string content are omitted, so the returned string’s length may be shorter than the editor’s as returned by getLength.
This is because non-text elements usually have a length of 1, so for every one of those you omit, your index will drift by 1.
A simple workaround for this is to replace any non-text elements with a newline character, which has length 1, and the added benefit of causing a search across it to fail (unless you let users search with newlines - maybe then you can pick another special character like a control character).
The following method should return a plain-text representation of your Quill contents whose length matches quill.getLength, and therefore should be able to be searched using whatever JavaScript text search method you want (eg indexOf for simple searches).
function textContents() {
return quill.getContents().ops
.reduce((text, op) => {
if (typeof op.insert === 'string') {
// If the op is a string insertion, just concat
return text + op.insert;
} else {
// Otherwise it's a block. Represent this as a newline,
// which will preserve the length of 1, and also prevent
// searches matching across the block
return text + '\n';
}
}, '');
}
Here's a rough example: https://codepen.io/alecgibson/pen/GLVzPb
Im getting more and more frustrated on why this is not doing what i want to. I need to have a text file that logs the last 10 buttons the user pressed, i tried in two ways but…
…this code only saves the last button pressed:
String [][] buttonsPressed = { {"Pressed one"}, {"Pressed two"} };
String[] sum;
void setup() {
size(700, 350);
sum = loadStrings("scores.txt");
}
void draw() {
}
void keyPressed() {
if ((key=='1')) {
saveStrings("scores.txt", buttonsPressed[0]);
}
if ((key=='2')) {
saveStrings("scores.txt", buttonsPressed[1]);
}
if ((key == ENTER)) {
printArray(sum);
}
}
…this code saves the buttons pressed but overwrites itself when i run the sketch again (probably has something to do with createWriter):
PrintWriter sum;
void setup() {
size(700, 350);
sum = createWriter("scores.txt");
}
void draw() {
}
void keyPressed() {
if ((key=='1')) {
sum.println("pressed one");
}
if ((key=='2')) {
sum.println("pressed two");
}
if ((key == ENTER)) {
sum.flush();
sum.close();
String[] lines = loadStrings("scores.txt");
for (int i = 0; i <= 9; i++) {
printArray("[" + i + "] " + lines[i]);
}
}
}
Is there a simple way to do this without using libraries ? Please get me in the right direction :)
Break your problem down into smaller steps.
Step 1: At the beginning of your program, read in the existing history file. Store them in some kind of data structure, like an array or an ArrayList.
Step 2: Make the data structure keep track of the last 10 buttons pressed. You'll need to write code that adds the newest button pressed to the end of the data structure, and if the data structure contains more than 10 items, you have to remove the oldest item. Maybe do this in a separate example sketch where you just print the data structure to the console and don't worry about outputting it to a file just yet.
Step 3: Output the data structure to a file. You don't have to worry about appending to the file because your data structure contains the entire history, so you can just overwrite the file with the entire data structure. You'll probably want to do this every time the data structure changes. Again, maybe do this in a separate example program before worrying about where the data is coming from: maybe make a program that outputs an array of random numbers every time the user clicks?
Focus on one small step at a time, and try creating small example programs for each step. Then when you get stuck, you can ask a specific question and provide an MCVE, and we'll go from there. Good luck.
I've been on and off creating a text adventure using a rudimentary engine I made for about a year.
For the story, I have a object array(is that what it's called?) with various story data stuff that I parse through
I've been told that using it the way I am is stupid because it's supposed to be used for other stuff but I only use it because it was easy to learn how to parse the data since I was a beginner
It's getting tedious writing the story and doing stuff for each part (creating the backgrounds and such) since it's so long.
Is there any kind of way I can make it easier for me to write the story?
Here's the object array with a single part set up (with choices)
public static var parts:Object =
{
"0":
{
"text":"Text here",
"choices":
{
"response1":
{
"text":"Response1",
"nextPart":"1"
},
"response2":
{
"text":"Response2",
"nextPart":"2"
}
},
"background": Assets.AssetClass.Background1,
"BGM":"bg1"
},
}
Here's an example of how my engine deals with parts and changing them:
I have a input checker to check when enter is pressed and then do stuff depending on what is on the screen
public function onEnter(button:KeyboardEvent):void
{
if (button.keyCode == 32 && !Won)
{
if (Dead && textFinished && !choosing) // pressing enter while dead and the text is still writing
{
curPart = parts[curPart]["lastPart"] // lastPart will only be stored in parts that have the player die
textFinished = false
Dead = false;
myTextField.text = ""
counter = 0;
sInt = setInterval(addCharackter, textSpeed)
if (stage.getChildByName("cText"))
{
stage.removeChild(continueText)
}
if (parts[curPart].hasOwnProperty("background")) //check if the background needs to change.
{
if (stage.getChildByName("img"))
{
stage.removeChild(background)
}
background = new Background(parts[curPart], 800, 600)
stage.addChildAt(background, 0)
}
}
if (!textFinished && !choosing)// pressing enter when there's no choices on the screen and the text isn't finished and the text is still writing
{
this.myTextField.text = this.parts[this.curPart]["text"];
clearInterval(this.sInt);
this.textFinished = true;
if (parts[curPart].hasOwnProperty("choices"))
{
choosing = true
createOptions(); // function for parsing through the responses bit of that part and displaying them
}
else
{
stage.addChildAt(continueText, 2)
}
if (parts[curPart].hasOwnProperty("lastPart"))
{
Dead = true;
dead()
}
}
else if (textFinished && !choosing && !Dead) // pressing enter if there's no choices on the screen and there's no choices (it'll take you to the next part)
{
trace("Text finished!!")
curPart = parts[curPart]["nextPart"]
myTextField.text = ""
counter = 0;
sInt = setInterval(addCharackter, textSpeed)
textFinished = false;
if (parts[curPart].hasOwnProperty("background"))
{
if (stage.getChildByName("img"))
{
trace("Removed!")
stage.removeChild(background)
}
background = new Background(parts[curPart], 800, 600)
stage.addChildAt(background, 0)
}
if (parts[curPart].hasOwnProperty("BGM")) // does the current part have a new background music?
{
trace("Music!!!!")
sndBGMusic = musicArray[parts[curPart]["BGM"]]
sndBGMusicChannel.stop()
sndBGMusicChannel = sndBGMusic.play(0, 9999999999)
stage.addChildAt(background, 0)
}
stage.removeChild(continueText)
}
}
}
A couple ideas here. These are just things I would do differently than what you have done. I don't guarantee that they are better in any way, but see what you think.
I would have a global variable for _curPart. And I would have a custom class called Part. That class would have properties like _BGM, _bgImage etc. It could have a _choicesArray as a property as well. I'd have other global variables like _hasCandle. Or you can store items in an array and if you need the candle just check if candle is in the array. These global variables will persist from one part to the next.
Then you can access the properties of the part you are in by doing _curPart._bgImage. To me, that looks and feels cleaner.
And to create a new part it could look like (incomplete):
var p15:Part = new Part();
p15._bgImage = image15;
p15._BGM = song10;
//...
The last thing I'd recommend is to try to refactor where you can. For example, where you have //pressing enter if there's no choic... replace all of that code in that bracket with a one or a few function calls (whatever makes the most sense and allows you to reuse code). It just makes it easier to see what's going on, I think. So instead of all these if blocks, just a function like nextPart(); and then that function will have all your if blocks in it. Make sense? Personal preference, but when things are getting complicated, refactoring helps me clear out the cobwebs. Just like you do with dead() and createOptions() but I'd just take it one step further. This won't make your code more efficient, but it might make writing your code more efficient which is paramount in my book (until it's not).