Java: Indexoutofrange what is going on? - automaton

Here is my code for a cellular automaton I am working on:
public class Life1D {
private Rule rule;
private int stepCount;
public static void main (String [ ] args) {
Life1D simulation = new Life1D ( );
simulation.processArgs (args);
simulation.producePBM ( );
}
// Print, in Portable Bitmap format, the image corresponding to the rule and step count
// specified on the command line.
public void producePBM ( ) {
int width = (stepCount*2+1);
System.out.println("P1 " + width + " " + (stepCount+1));
String prev_string = "";
// constructs dummy first line of rule
for (int i = 0; i < width; i++){
if (i == stepCount+1){
prev_string += "1";
} else {
prev_string += "0";
}
}
// contructs and prints out all lines prescribed by the rule, including the first
for (int i = 0; i < stepCount; i++) {
String next_string = "";
for (int j = 0; j < width; j++) {
// prints next line, one character at a time
System.out.print(prev_string.charAt(j) + " ");
// specifies cases for the edges as well as for normal inputs to Rule
if (j == 0) {
next_string += rule.output(0, prev_string.charAt(0), prev_string.charAt(1));
} else if (j == width-1) {
next_string += rule.output(prev_string.charAt(width-2), prev_string.charAt(width-1), 0);
} else {
String rule_input = prev_string.substring(j-1, j+2);
int first = rule_input.charAt(0);
int second = rule_input.charAt(1);
int third = rule_input.charAt(2);
next_string += rule.output(first, second, third);
}
}
// sets prev_string to next_string so that string will be the next string in line to be printed
prev_string = next_string;
System.out.println();
}
}
// Retrieve the command-line arguments, and convert them to values for the rule number
// and the timestep count.
private void processArgs (String [ ] args) {
if (args.length != 2) {
System.err.println ("Usage: java Life1D rule# rowcount");
System.exit (1);
}
try {
rule = new Rule (Integer.parseInt (args[0]));
} catch (Exception ex) {
System.err.println ("The first argument must specify a rule number.");
System.exit (1);
}
try {
stepCount = Integer.parseInt (args[1]);
} catch (Exception ex) {
System.err.println ("The second argument must specify the number of lines in the output.");
System.exit (1);
}
if (stepCount < 1) {
System.err.println ("The number of output lines must be a positive number.");
System.exit (1);
}
}
}
class Rule {
private int a, b, c;
private String rulebin;
public Rule (int ruleNum) {
rulebin = Integer.toBinaryString(ruleNum);
}
// Return the output that this rule prescribes for the given input.
// a, b, and c are each either 1 or 0; 4*a+2*b+c is the input for the rule.
public int output (int a, int b, int c) {
return rulebin.charAt(7 - 4*a + 2*b + c);
}
}
Here is the error message when I run it:
P1 7 4
0 Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 151
at java.lang.String.charAt(String.java:686)
at Rule.output(Life1D.java:90)
at Life1D.producePBM(Life1D.java:35)
at Life1D.main(Life1D.java:9)
What the heck? Why am I getting this error, and how can I fix it? I've been trying to find the error for hours, and it'll a blessing if I could be helped.

In this particular part you are converting integer to binary string:
rulebin = Integer.toBinaryString(ruleNum);
Now let suppose your parameters are:
first parameter = 12
second parameter = any number
Now when this code will convert this number into binary string then you will get:
rulebin = "1100" (length 4)
Now in this function:
public int output (int a, int b, int c) {
return rulebin.charAt(7 - 4*a + 2*b + c);
}
When a = b = c = 0 then this function will try to access your "rulebin's character 8" but length of your rulebin is 4. That's why you are getting String Index out of bound exception.
Note: I am not sure if you have put any restrictions on your input parameters but this can be a potential problem.

No! the problem is that you're passing char instead of int to
public int output (int a, int b, int c) {
return rulebin.charAt(7 - 4*a + 2*b + c);
}
I tried it and when the prevString.charAt(0) and prevString.charAt(1) were 0 it send to the output method those parameters (0,48,48) (try to debug it and you'll)
this cause the index out of range!
and also the convertion to binary string doesn't return 7 digits format..
UPDATE:
public class Lif1ID {
private Rule rule;
private int stepCount;
public static void main (String [ ] args) {
Lif1ID simulation = new Lif1ID ( );
simulation.processArgs (args);
simulation.producePBM ( );
}
// Print, in Portable Bitmap format, the image corresponding to the rule and step count
// specified on the command line.
public void producePBM ( ) {
int width = (stepCount*2+1);
System.out.println("P1 " + width + " " + (stepCount+1));
String prev_string = "";
// constructs dummy first line of rule
for (int i = 0; i < width; i++){
if (i == stepCount+1){
prev_string += "1";
} else {
prev_string += "0";
}
}
// contructs and prints out all lines prescribed by the rule, including the first
for (int i = 0; i < stepCount; i++) {
String next_string = "";
for (int j = 0; j < width; j++) {
// prints next line, one character at a time
System.out.print(prev_string.charAt(j) + " ");
// specifies cases for the edges as well as for normal inputs to Rule
if (j == 0) {
// take a look at the 'getNumericValue' Method.. in your version it didn't pass 0 or 1, now it does..
next_string += rule.output(0, Character.getNumericValue(prev_string.charAt(0)), Character.getNumericValue(prev_string.charAt(1)));
} else if (j == width-1) {
next_string += rule.output(prev_string.charAt(width-2), prev_string.charAt(width-1), 0);
} else {
String rule_input = prev_string.substring(j-1, j+2);
int first = Character.getNumericValue(rule_input.charAt(0));
int second = Character.getNumericValue(rule_input.charAt(1));
int third = Character.getNumericValue(rule_input.charAt(2));
next_string += rule.output(first, second, third);
}
}
// sets prev_string to next_string so that string will be the next string in line to be printed
prev_string = next_string;
System.out.println();
}
}
// Retrieve the command-line arguments, and convert them to values for the rule number
// and the timestep count.
private void processArgs (String [ ] args) {
if (args.length != 2) {
System.err.println ("Usage: java Life1D rule# rowcount");
System.exit (1);
}
try {
rule = new Rule (Integer.parseInt(args[0]));
} catch (Exception ex) {
System.err.println ("The first argument must specify a rule number.");
System.exit (1);
}
try {
stepCount = Integer.parseInt (args[1]);
} catch (Exception ex) {
System.err.println ("The second argument must specify the number of lines in the output.");
System.exit (1);
}
if (stepCount < 1) {
System.err.println ("The number of output lines must be a positive number.");
System.exit (1);
}
}
}
class Rule {
private int a, b, c;
private String rulebin;
public Rule (int ruleNum) {
rulebin = convertToBinary(ruleNum);
}
private String convertToBinary(int input) // get the binary presentation as you want
{ // if the input is 2 you'll get "00000010"
String binary = "";
for (int i = 0; i < 8; i++){
if ((1 << i & input) != 0)
binary += "1";
else
binary+= "0";
}
binary = new StringBuffer(binary).reverse().toString();
return binary;
}
// Return the output that this rule prescribes for the given input.
// a, b, and c are each either 1 or 0; 4*a+2*b+c is the input for the rule.
public char output (int a, int b, int c) { // here you want to return a char, no?
return rulebin.charAt(7 - 4*a + 2*b + c); // there is a problem with your formula
}
}

Related

to read the images in order in opencv C++ using glob [duplicate]

I'm sorting strings that are comprised of text and numbers.
I want the sort to sort the number parts as numbers, not alphanumeric.
For example I want: abc1def, ..., abc9def, abc10def
instead of: abc10def, abc1def, ..., abc9def
Does anyone know an algorithm for this (in particular in c++)
Thanks
I asked this exact question (although in Java) and got pointed to http://www.davekoelle.com/alphanum.html which has an algorithm and implementations of it in many languages.
Update 14 years later: Dave Koelle’s blog has gone off line and I can’t find his actual algorithm, but here’s an implementation.
https://github.com/cblanc/koelle-sort
Several natural sort implementations for C++ are available. A brief review:
natural_sort<> - based on Boost.Regex.
In my tests, it's roughly 20 times slower than other options.
Dirk Jagdmann's alnum.hpp, based on Dave Koelle's alphanum algorithm
Potential integer overlow issues for values over MAXINT
Martin Pool's natsort - written in C, but trivially usable from C++.
The only C/C++ implementation I've seen to offer a case insensitive version, which would seem to be a high priority for a "natural" sort.
Like the other implementations, it doesn't actually parse decimal points, but it does special case leading zeroes (anything with a leading 0 is assumed to be a fraction), which is a little weird but potentially useful.
PHP uses this algorithm.
This is known as natural sorting. There's an algorithm here that looks promising.
Be careful of problems with non-ASCII characters (see Jeff's blog entry on the subject).
Partially reposting my another answer:
bool compareNat(const std::string& a, const std::string& b){
if (a.empty())
return true;
if (b.empty())
return false;
if (std::isdigit(a[0]) && !std::isdigit(b[0]))
return true;
if (!std::isdigit(a[0]) && std::isdigit(b[0]))
return false;
if (!std::isdigit(a[0]) && !std::isdigit(b[0]))
{
if (a[0] == b[0])
return compareNat(a.substr(1), b.substr(1));
return (toUpper(a) < toUpper(b));
//toUpper() is a function to convert a std::string to uppercase.
}
// Both strings begin with digit --> parse both numbers
std::istringstream issa(a);
std::istringstream issb(b);
int ia, ib;
issa >> ia;
issb >> ib;
if (ia != ib)
return ia < ib;
// Numbers are the same --> remove numbers and recurse
std::string anew, bnew;
std::getline(issa, anew);
std::getline(issb, bnew);
return (compareNat(anew, bnew));
}
toUpper() function:
std::string toUpper(std::string s){
for(int i=0;i<(int)s.length();i++){s[i]=toupper(s[i]);}
return s;
}
Usage:
std::vector<std::string> str;
str.push_back("abc1def");
str.push_back("abc10def");
...
std::sort(str.begin(), str.end(), compareNat);
To solve what is essentially a parsing problem a state machine (aka finite state automaton) is the way to go. Dissatisfied with the above solutions i wrote a simple one-pass early bail-out algorithm that beats C/C++ variants suggested above in terms of performance, does not suffer from numerical datatype overflow errors, and is easy to modify to add case insensitivity if required.
sources can be found here
For those that arrive here and are already using Qt in their project, you can use the QCollator class. See this question for details.
Avalanchesort is a recursive variation of naturall sort, whiche merge runs, while exploring the stack of sorting-datas. The algorithim will sort stable, even if you add datas to your sorting-heap, while the algorithm is running/sorting.
The search-principle is simple. Only merge runs with the same rank.
After finding the first two naturell runs (rank 0), avalanchesort merge them to a run with rank 1. Then it call avalanchesort, to generate a second run with rank 1 and merge the two runs to a run with rank 2. Then it call the avalancheSort to generate a run with rank 2 on the unsorted datas....
My Implementation porthd/avalanchesort divide the sorting from the handling of the data using interface injection. You can use the algorithmn for datastructures like array, associative arrays or lists.
/**
* #param DataListAvalancheSortInterface $dataList
* #param DataRangeInterface $beginRange
* #param int $avalancheIndex
* #return bool
*/
public function startAvalancheSort(DataListAvalancheSortInterface $dataList)
{
$avalancheIndex = 0;
$rangeResult = $this->avalancheSort($dataList, $dataList->getFirstIdent(), $avalancheIndex);
if (!$dataList->isLastIdent($rangeResult->getStop())) {
do {
$avalancheIndex++;
$lastIdent = $rangeResult->getStop();
if ($dataList->isLastIdent($lastIdent)) {
$rangeResult = new $this->rangeClass();
$rangeResult->setStart($dataList->getFirstIdent());
$rangeResult->setStop($dataList->getLastIdent());
break;
}
$nextIdent = $dataList->getNextIdent($lastIdent);
$rangeFollow = $this->avalancheSort($dataList, $nextIdent, $avalancheIndex);
$rangeResult = $this->mergeAvalanche($dataList, $rangeResult, $rangeFollow);
} while (true);
}
return $rangeResult;
}
/**
* #param DataListAvalancheSortInterface $dataList
* #param DataRangeInterface $range
* #return DataRangeInterface
*/
protected function findRun(DataListAvalancheSortInterface $dataList,
$startIdent)
{
$result = new $this->rangeClass();
$result->setStart($startIdent);
$result->setStop($startIdent);
do {
if ($dataList->isLastIdent($result->getStop())) {
break;
}
$nextIdent = $dataList->getNextIdent($result->getStop());
if ($dataList->oddLowerEqualThanEven(
$dataList->getDataItem($result->getStop()),
$dataList->getDataItem($nextIdent)
)) {
$result->setStop($nextIdent);
} else {
break;
}
} while (true);
return $result;
}
/**
* #param DataListAvalancheSortInterface $dataList
* #param $beginIdent
* #param int $avalancheIndex
* #return DataRangeInterface|mixed
*/
protected function avalancheSort(DataListAvalancheSortInterface $dataList,
$beginIdent,
int $avalancheIndex = 0)
{
if ($avalancheIndex === 0) {
$rangeFirst = $this->findRun($dataList, $beginIdent);
if ($dataList->isLastIdent($rangeFirst->getStop())) {
// it is the last run
$rangeResult = $rangeFirst;
} else {
$nextIdent = $dataList->getNextIdent($rangeFirst->getStop());
$rangeSecond = $this->findRun($dataList, $nextIdent);
$rangeResult = $this->mergeAvalanche($dataList, $rangeFirst, $rangeSecond);
}
} else {
$rangeFirst = $this->avalancheSort($dataList,
$beginIdent,
($avalancheIndex - 1)
);
if ($dataList->isLastIdent($rangeFirst->getStop())) {
$rangeResult = $rangeFirst;
} else {
$nextIdent = $dataList->getNextIdent($rangeFirst->getStop());
$rangeSecond = $this->avalancheSort($dataList,
$nextIdent,
($avalancheIndex - 1)
);
$rangeResult = $this->mergeAvalanche($dataList, $rangeFirst, $rangeSecond);
}
}
return $rangeResult;
}
protected function mergeAvalanche(DataListAvalancheSortInterface $dataList, $oddListRange, $evenListRange)
{
$resultRange = new $this->rangeClass();
$oddNextIdent = $oddListRange->getStart();
$oddStopIdent = $oddListRange->getStop();
$evenNextIdent = $evenListRange->getStart();
$evenStopIdent = $evenListRange->getStop();
$dataList->initNewListPart($oddListRange, $evenListRange);
do {
if ($dataList->oddLowerEqualThanEven(
$dataList->getDataItem($oddNextIdent),
$dataList->getDataItem($evenNextIdent)
)) {
$dataList->addListPart($oddNextIdent);
if ($oddNextIdent === $oddStopIdent) {
$restTail = $evenNextIdent;
$stopTail = $evenStopIdent;
break;
}
$oddNextIdent = $dataList->getNextIdent($oddNextIdent);
} else {
$dataList->addListPart($evenNextIdent);
if ($evenNextIdent === $evenStopIdent) {
$restTail = $oddNextIdent;
$stopTail = $oddStopIdent;
break;
}
$evenNextIdent = $dataList->getNextIdent($evenNextIdent);
}
} while (true);
while ($stopTail !== $restTail) {
$dataList->addListPart($restTail);
$restTail = $dataList->getNextIdent($restTail);
}
$dataList->addListPart($restTail);
$dataList->cascadeDataListChange($resultRange);
return $resultRange;
}
}
My algorithm with test code of java version. If you want to use it in your project you can define a comparator yourself.
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;
public class FileNameSortTest {
private static List<String> names = Arrays.asList(
"A__01__02",
"A__2__02",
"A__1__23",
"A__11__23",
"A__3++++",
"B__1__02",
"B__22_13",
"1_22_2222",
"12_222_222",
"2222222222",
"1.sadasdsadsa",
"11.asdasdasdasdasd",
"2.sadsadasdsad",
"22.sadasdasdsadsa",
"3.asdasdsadsadsa",
"adsadsadsasd1",
"adsadsadsasd10",
"adsadsadsasd3",
"adsadsadsasd02"
);
public static void main(String...args) {
List<File> files = new ArrayList<>();
names.forEach(s -> {
File f = new File(s);
try {
if (!f.exists()) {
f.createNewFile();
}
files.add(f);
} catch (IOException e) {
e.printStackTrace();
}
});
files.sort(Comparator.comparing(File::getName));
files.forEach(f -> System.out.print(f.getName() + " "));
System.out.println();
files.sort(new Comparator<File>() {
boolean caseSensitive = false;
int SPAN_OF_CASES = 'a' - 'A';
#Override
public int compare(File left, File right) {
char[] csLeft = left.getName().toCharArray(), csRight = right.getName().toCharArray();
boolean isNumberRegion = false;
int diff=0, i=0, j=0, lenLeft=csLeft.length, lenRight=csRight.length;
char cLeft = 0, cRight = 0;
for (; i<lenLeft && j<lenRight; i++, j++) {
cLeft = getCharByCaseSensitive(csLeft[i]);
cRight = getCharByCaseSensitive(csRight[j]);
boolean isNumericLeft = isNumeric(cLeft), isNumericRight = isNumeric(cRight);
if (isNumericLeft && isNumericRight) {
// Number start!
if (!isNumberRegion) {
isNumberRegion = true;
// Remove prefix '0'
while (i < lenLeft && cLeft == '0') i++;
while (j < lenRight && cRight == '0') j++;
if (i == lenLeft || j == lenRight) break;
}
// Diff start: calculate the diff value.
if (cLeft != cRight && diff == 0)
diff = cLeft - cRight;
} else {
if (isNumericLeft != isNumericRight) {
// One numeric and one char.
if (isNumberRegion)
return isNumericLeft ? 1 : -1;
return cLeft - cRight;
} else {
// Two chars: if (number) diff don't equal 0 return it.
if (diff != 0)
return diff;
// Calculate chars diff.
diff = cLeft - cRight;
if (diff != 0)
return diff;
// Reset!
isNumberRegion = false;
diff = 0;
}
}
}
// The longer one will be put backwards.
return (i == lenLeft && j == lenRight) ? cLeft - cRight : (i == lenLeft ? -1 : 1) ;
}
private boolean isNumeric(char c) {
return c >= '0' && c <= '9';
}
private char getCharByCaseSensitive(char c) {
return caseSensitive ? c : (c >= 'A' && c <= 'Z' ? (char) (c + SPAN_OF_CASES) : c);
}
});
files.forEach(f -> System.out.print(f.getName() + " "));
}
}
The output is,
1.sadasdsadsa 11.asdasdasdasdasd 12_222_222 1_22_2222 2.sadsadasdsad 22.sadasdasdsadsa 2222222222 3.asdasdsadsadsa A__01__02 A__11__23 A__1__23 A__2__02 A__3++++ B__1__02 B__22_13 adsadsadsasd02 adsadsadsasd1 adsadsadsasd10 adsadsadsasd3
1.sadasdsadsa 1_22_2222 2.sadsadasdsad 3.asdasdsadsadsa 11.asdasdasdasdasd 12_222_222 22.sadasdasdsadsa 2222222222 A__01__02 A__1__23 A__2__02 A__3++++ A__11__23 adsadsadsasd02 adsadsadsasd1 adsadsadsasd3 adsadsadsasd10 B__1__02 B__22_13
Process finished with exit code 0
// -1: s0 < s1; 0: s0 == s1; 1: s0 > s1
static int numericCompare(const string &s0, const string &s1) {
size_t i = 0, j = 0;
for (; i < s0.size() && j < s1.size();) {
string t0(1, s0[i++]);
while (i < s0.size() && !(isdigit(t0[0]) ^ isdigit(s0[i]))) {
t0.push_back(s0[i++]);
}
string t1(1, s1[j++]);
while (j < s1.size() && !(isdigit(t1[0]) ^ isdigit(s1[j]))) {
t1.push_back(s1[j++]);
}
if (isdigit(t0[0]) && isdigit(t1[0])) {
size_t p0 = t0.find_first_not_of('0');
size_t p1 = t1.find_first_not_of('0');
t0 = p0 == string::npos ? "" : t0.substr(p0);
t1 = p1 == string::npos ? "" : t1.substr(p1);
if (t0.size() != t1.size()) {
return t0.size() < t1.size() ? -1 : 1;
}
}
if (t0 != t1) {
return t0 < t1 ? -1 : 1;
}
}
return i == s0.size() && j == s1.size() ? 0 : i != s0.size() ? 1 : -1;
}
I am not very sure if it is you want, anyway, you can have a try:-)

How to write Modem Drivers for non-subnero modems?

How can i use the existing modems which is not subnero with UnetStack (basically is not support UnetStack natively) ? I was gone through the post in detailed, but unfortunately had bad compilation issues. Can anyone point me to right direction ?
Below is the detailed error i encountered:
BUG! exception in phase 'semantic analysis' in source unit 'Script66.groovy' The lookup for MyModemDriver caused a failed compilation. There should not have been any compilation from this call.
Here is my code:
import org.arl.fjage.*
import org.arl.unet.*
import com.fazecast.jSerialComm.*
import org.arl.unet.api.UnetSocket
import org.arl.unet.phy.RxFrameNtf
import org.arl.unet.phy.TxFrameNtf
class PopotoModemDriver extends UnetAgent {
// Using UnetSocket to connect to network modem ('ip',port)
def sock = UnetSocket('192.168.0.42', 1100)
AgentID notify // notification topic
int plvl = 170 // default power level setting
#Override
void setup() {
notify = topic()
register Services.PHYSICAL
register Services.DATAGRAM
}
#Override
void shutdown() {
sock.close()
}
#Override
Message processRequest(Message req) {
if (req instanceof DatagramReq) {
String s = "AT+TX:" + req.to + "," + req.data.encodeHex() + "\n"
byte[] b = s.getBytes()
sock.writeBytes(b, b.length)
add new OneShotBehavior({
send new TxFrameNtf(req)
})
return new Message(req, Performative.AGREE)
}
return null
}
int getMTU() {
return 32 // frame size
}
boolean getRxEnable() {
return true
}
float getPropagationSpeed() {
return 1500 // assume sound speed is 1500 m/s
}
int getTimestampedTxDelay() {
return 0 // our modem doesn't support timestamped transmissions
}
long getTime() {
return 1000*System.currentTimeMillis() // use system clock for timing in µs
}
boolean getBusy() {
return false
}
float getRefPowerLevel() {
return 0 // our modem uses absolute power levels in dB re uPa # 1m
}
float getMaxPowerLevel() {
return 180 // our modem can transmit at max power level of 180 dB
}
float getMinPowerLevel() {
return 120 // ... and a min power level of 120 dB
}
int getMTU(int ch) {
return 32 // frame size
}
float getFrameDuration(int ch) {
return getMTU(ch)/getDataRate(ch)
}
float getPowerLevel(int ch) {
return plvl
}
int getErrorDetection(int ch) {
return 0
}
int getFrameLength(int ch) {
return getMTU(ch) // fixed frame size
}
int getMaxFrameLength(int ch) {
return getMTU(ch) // fixed frame size
}
int getFec(int ch) {
return 0
}
List getFecList(int ch) {
return null
}
float getDataRate(int ch) {
return 320.0 // data rate of 320 bps
}
float setPowerLevel(int ch, float x) {
plvl = x
if (plvl < getMinPowerLevel()) plvl = getMinPowerLevel()
if (plvl > getMaxPowerLevel()) plvl = getMaxPowerLevel()
String s = "AT+TPL:" + plvl + "\n"
byte[] b = s.getBytes()
sock.writeBytes(b, b.length)
return plvl
}
#Override
void startup() {
sock.openPort()
add new CyclicBehavior({
int n = sock.bytesAvailable()
if (n == 0) Thread.sleep(20)
else {
// data available
byte[] buf = new byte[n]
sock.readBytes(buf, n)
parseRxData(new String(buf))
}
})
}
String data = ''
void parseRxData(String s) {
data += s
int n = data.indexOf('\n')
if (n < 0) return
s = data.substring(0, n)
data = data.substring(n)
if (s.startsWith("AT+RX:")) {
int addr = s.substring(6,9) as int
byte[] bytes = s.substring(10).decodeHex()
send new RxFrameNtf(
recipient: notify,
from: addr,
data: bytes,
bits: 8*bytes.length,
rxTime: 1000*System.currentTimeMillis()
)
}
}
}
#manuignatius is right, Groovy complains about this when there is a syntax error in a dynamically loaded Groovy class.
To get a more detailed stack trace on the error, you can manually invoke the Groovy compiler. Set your CLASSPATH environment variable to include all the jars in the lib folder in your local UnetStack installation. Then simply run groovyc MyModemDriver.groovy, and it should show you compilation errors, if any. The compiled .class file that is produced on successful compilation can then be copied to the classes folder in UnetStack/modem instead of the source code.

How to get first character from words in flutter dart?

Let's say we have a name set to "Ben Bright". I want to output to the user "BB", with the first characters of each word. I tried with the split() method, but I failed to do it with dart.
String getInitials(bank_account_name) {
List<String> names = bank_account_name.split(" ");
String initials;
for (var i = 0; i < names.length; i++) {
initials = '${names[i]}';
}
return initials;
}
Allow me to give a shorter solution than the other mentioned:
void main() {
print(getInitials('')); //
print(getInitials('Ben')); // B
print(getInitials('Ben ')); // B
print(getInitials('Ben Bright')); // BB
print(getInitials('Ben Bright Big')); // BB
}
String getInitials(String bank_account_name) => bank_account_name.isNotEmpty
? bank_account_name.trim().split(' ').map((l) => l[0]).take(2).join()
: '';
The take(2) part ensures we only take up to two letters.
EDIT (7th October 2021):
Or if we must be able to handle multiple spaces between the words we can do (thanks #StackUnderflow for notice):
void main() {
print(getInitials('')); //
print(getInitials('Ben')); // B
print(getInitials('Ben ')); // B
print(getInitials('Ben Bright')); // BB
print(getInitials('Ben Bright Big')); // BB
print(getInitials('Ben Bright Big')); // BB
}
String getInitials(String bankAccountName) => bankAccountName.isNotEmpty
? bankAccountName.trim().split(RegExp(' +')).map((s) => s[0]).take(2).join()
: '';
Notice that split takes a RegExp(' +') compared to the original solution.
Just a slight modification since you only need the first letters
String getInitials(bank_account_name) {
List<String> names = bank_account_name.split(" ");
String initials = "";
int numWords = 2;
if(numWords < names.length) {
numWords = names.length;
}
for(var i = 0; i < numWords; i++){
initials += '${names[i][0]}';
}
return initials;
}
Edit:
You can set the value of num_words to print the intials of those many words.
If the bank_account_name is a 0 letter word, then return an empty string
If the bank_account_name contains lesser words than num_words, print the initials of all the words in bank_account_name.
var string = 'William Henry Gates';
var output = getInitials(string: string, limitTo: 1); // W
var output = getInitials(string: string, limitTo: 2); // WH
var output = getInitials(string: string); // WHG
String getInitials({String string, int limitTo}) {
var buffer = StringBuffer();
var split = string.split(' ');
for (var i = 0 ; i < (limitTo ?? split.length); i ++) {
buffer.write(split[i][0]);
}
return buffer.toString();
}
A more general solution can be found below. It takes care of empty strings, single word strings and situations where anticipated word count is less than actual word count:
static String getInitials(String string, {int limitTo}) {
var buffer = StringBuffer();
var wordList = string.trim().split(' ');
if (string.isEmpty)
return string;
// Take first character if string is a single word
if (wordList.length <= 1)
return string.characters.first;
/// Fallback to actual word count if
/// expected word count is greater
if (limitTo != null && limitTo > wordList.length) {
for (var i = 0; i < wordList.length; i++) {
buffer.write(wordList[i][0]);
}
return buffer.toString();
}
// Handle all other cases
for (var i = 0; i < (limitTo ?? wordList.length); i++) {
buffer.write(wordList[i][0]);
}
return buffer.toString();
}
Edit:
I actually use this for CircleAvatars with no images in my projects.
I used CopsOnRoad solution but I was getting the following error.
RangeError (index): Invalid value: Only valid value is 0: 1
So I modified it to
String getInitials(String string, [int limitTo = 2]) {
if (string == null || string.isEmpty) {
return '';
}
var buffer = StringBuffer();
var split = string.split(' ');
//For one word
if (split.length == 1) {
return string.substring(0, 1);
}
for (var i = 0; i < (limitTo ?? split.length); i++) {
buffer.write(split[i][0]);
}
return buffer.toString();
}
Here are some tests in case you are interested
void main() {
group('getInitials', () {
test('should process one later word name correctly', () {
final result = getInitials('J');
expect(result, 'J');
});
test('should process one word name correctly', () {
final result = getInitials('John');
expect(result, 'J');
});
test('should process two word name correctly', () {
final result = getInitials('John Mamba');
expect(result, 'JM');
});
test('should process more than two word name correctly', () {
final result = getInitials('John Mamba Kanzu');
expect(result, 'JM');
});
test('should return empty string when name is null', () {
final result = getInitials(null);
expect(result, '');
});
test('should return empty string when name is empty', () {
final result = getInitials('');
expect(result, '');
});
});
}
String getInitials(full_name) {
List<String> names = full_name.split(" ");
print("org::: $full_name");
print("list ::: $names");
print("Substring ::: ${names[0].substring(0,1)}");
String initials = "";
int numWords = 2;
numWords = names.length;
for(var i = 0; i < numWords; i++)
{
initials += '${names[i].substring(0,1)}';
print("the initials are $initials");
}
return initials;
}
On Nov, 2022
Working solution using Regex:
String getInitials(String string) => string.isNotEmpty
? string.trim().split(RegExp(' +')).map((s) => s[0]).join()
: '' ;

How can I solve the duplicates of pending order issues?

My code below places sell pending orders when certain candle patterns are met on the H_1 chart. But duplicate pending orders are created when I change the chart timeframe and return to H_1. Also old orders that should have hit stop loss or take profit seem to still be open.
I need to have multiple pending orders, but the duplicates and orders that should have closed are not wanted. How can I solve this?
string prefix = "HG";
const int N_bars = 1;
int numBars = 1;
int numBarsArray[];
int tempVal = 0;
int NumOfDisplayBars = 300;
int count = 0;
extern double lotSize = 0.01;
int magicnumber = 1337;
void showRectangles()
{
for (int i=NumOfDisplayBars;i>=1;i--)
{
if(isBearishEngulfing(i))
{
drawBearRectangle(i + 1,iHigh(_Symbol,0,i + 1),iOpen(_Symbol,0,i + 1));
}
}
}
bool isBearishEngulfing(int current)
{
if( (iClose(_Symbol,0,current ) < iOpen( _Symbol,0,current ))
&& (iClose(_Symbol,0,current + 1) > iOpen( _Symbol,0,current + 1))
&& (iOpen( _Symbol,0,current ) > iClose(_Symbol,0,current + 1))
&& (iClose(_Symbol,0,current ) < iOpen( _Symbol,0,current + 1))
)
return true;
return false;
}
bool drawBearRectangle(int candleInt,const double top,const double bottom)
{
const datetime starts = iTime(_Symbol,0,candleInt);
const datetime ends = starts+PeriodSeconds()*N_bars;
const string name = prefix+"_"+(candleInt>0?"DEMAND":"SUPPLY")+"_"+TimeToString(starts);
if(!ObjectCreate(0,name,OBJ_RECTANGLE,0,0,0,0,0))
{
printf("%i %s: failed to create %s. error=%d",__LINE__,__FILE__,name,_LastError);
return false;
}
ObjectSetInteger(0,name,OBJPROP_TIME1, starts);
ObjectSetInteger(0,name,OBJPROP_TIME2, ends);
ObjectSetDouble( 0,name,OBJPROP_PRICE1,bottom);
ObjectSetDouble( 0,name,OBJPROP_PRICE2,top);
ObjectSetInteger(0,name,OBJPROP_COLOR, clrChocolate);
ObjectSetInteger(0,name,OBJPROP_STYLE, STYLE_DASHDOT);
ObjectSetInteger(0,name,OBJPROP_WIDTH, 1);
ObjectSetInteger(0,name,OBJPROP_FILL, false);
if(_Period == 60){
double entryPrice=bottom-3*_Point;
double stopLoss=top;
double slDist=fabs(entryPrice-stopLoss);
double dTakeProfit=entryPrice-2*slDist;
int ticketSell = OrderSend(Symbol(),OP_SELLLIMIT,lotSize, entryPrice,0,stopLoss,dTakeProfit,"SellOrder",magicnumber,0,Red);
}
return true;
}
void OnDeinit(const int reason){ObjectsDeleteAll(0,prefix);}
void OnTick()
{
if(!isNewBar())
return; // not necessary but waste of time to check every second
showRectangles();
}
bool isNewBar()
{
static datetime lastbar;
datetime curbar = (datetime)SeriesInfoInteger(_Symbol,_Period,SERIES_LASTBAR_DATE);
if(lastbar != curbar)
{
lastbar = curbar;
return true;
}
return false;
}
Q : How can I solve the duplicates of pending order issues?... when I change the chart timeframe and return to H_1.
Well, this is rather a feature of the MQL4/5 code-execution ecosystem.
Solution:
Configure a preventive checkmark, setup in MT4-Terminal in Tools > Options > Expert Advisor-tab so as to become:
[x] Disable automated trading when the chart symbol or period has been changed

Java: Indexoutofbound in Cellualar Automaton

Here is my code for a cellular automaton I am working on:
UPDATE:
public class Lif1ID {
private Rule rule;
private int stepCount;
public static void main (String [ ] args) {
Lif1ID simulation = new Lif1ID ( );
simulation.processArgs (args);
simulation.producePBM ( ); LINE 9
}
// Print, in Portable Bitmap format, the image corresponding to the rule and step count
// specified on the command line.
public void producePBM ( ) {
int width = (stepCount*2+1);
System.out.println("P1 " + width + " " + (stepCount+1));
String prev_string = "";
// constructs dummy first line of rule
for (int i = 0; i < width; i++){
if (i == stepCount+1){
prev_string += "1";
} else {
prev_string += "0";
}
}
// contructs and prints out all lines prescribed by the rule, including the first
for (int i = 0; i < stepCount; i++) {
String next_string = "";
for (int j = 0; j < width; j++) {
// prints next line, one character at a time
System.out.print(prev_string.charAt(j) + " ");
// specifies cases for the edges as well as for normal inputs to Rule
if (j == 0) {
next_string += rule.output(0, Character.getNumericValue(prev_string.charAt(0)), Character.getNumericValue(prev_string.charAt(1)));
} else if (j == width-1) {
next_string += rule.output(Character.getNumericValue(prev_string.charAt(width-2)), Character.getNumericValue(prev_string.charAt(width-1)), 0);
} else {
String rule_input = prev_string.substring(j-1, j+2);
int first = Character.getNumericValue(rule_input.charAt(0));
int second = Character.getNumericValue(rule_input.charAt(1));
int third = Character.getNumericValue(rule_input.charAt(2));
next_string += rule.output(first, second, third); LINE 43
}
}
// sets prev_string to next_string so that string will be the next string in line to be printed
prev_string = next_string;
System.out.println();
}
}
// Retrieve the command-line arguments, and convert them to values for the rule number
// and the timestep count.
private void processArgs (String [ ] args) {
if (args.length != 2) {
System.err.println ("Usage: java Life1D rule# rowcount");
System.exit (1);
}
try {
rule = new Rule (Integer.parseInt(args[0]));
} catch (Exception ex) {
System.err.println ("The first argument must specify a rule number.");
System.exit (1);
}
try {
stepCount = Integer.parseInt (args[1]);
} catch (Exception ex) {
System.err.println ("The second argument must specify the number of lines in the output.");
System.exit (1);
}
if (stepCount < 1) {
System.err.println ("The number of output lines must be a positive number.");
System.exit (1);
}
}
}
class Rule {
private int a, b, c;
private String rulebin;
public Rule (int ruleNum) {
rulebin = convertToBinary(ruleNum);
}
private String convertToBinary(int input) // get the binary presentation as you want
{ // if the input is 2 you'll get "00000010"
String binary = "";
for (int i = 0; i < 8; i++){
if ((1 << i & input) != 0)
binary += "1";
else
binary+= "0";
}
binary = new StringBuffer(binary).reverse().toString();
return binary;
}
// Return the output that this rule prescribes for the given input.
// a, b, and c are each either 1 or 0; 4*a+2*b+c is the input for the rule.
public char output (int a, int b, int c) {
return rulebin.charAt(7 - 4*a + 2*b + c); LINE 106
}
}
Here is the error message I get when I type in rule 30 with 3 timesteps:
java Life1D 30 3
UPDATED error message:
P1 7 4
0 0 0 0Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 151
at java.lang.String.charAt(String.java:686)
at Rule.output(Life1D.java:106)
at Life1D.producePBM(Life1D.java:43)
at Life1D.main(Life1D.java:9)
The corresponding lines are noted in the code. Why am I getting this error, and how can I fix it? I've been trying to find the error for hours, and it'll a blessing if I could be helped.
The problem is that Rule.output() expects three int parameters, but what you're calling it with on the line
next_string += rule.output(0, prev_string.charAt(0), prev_string.charAt(1));
is actually an int and then 2 chars. Now, the actual character is '0', but due to the implicit conversion the language does for you, you get the ASCII code of '0', which is 48 and that's what's passed to the function Rule.output().
Now, to fix this problem you need to use the method Character.getNumericValue() like so:
next_string += rule.output(0, Character.getNumericValue(prev_string.charAt(0)), Character.getNumericValue(prev_string.charAt(1)));
Don't forget to change the other two invocations of Rule.output()
However, note that this is not the only problem in your code, as I'm still getting String index out of range: 7, because the parameters with which the Rule.output() method is called with are now all 0, but I've answered your original question. If you need more help, let me know.

Resources