So for extra credit for my math class I'm writing a program to visualize pi. Every 6 digits is converted to a hex color.
However, I'm running into an error when I try to scale the colors (since with 2 digits each for r, g, and b I can only go up to 99 and I want to go to 255). I go through a few thousand digits of pi and run this scale function on each set of 6 and then write it to a pixel in a BufferedImage, but I keep getting a StringIndexOutOfBoundsException. When I tried setting retArray[i+1] = subArray[0] I get the same error but this time at line 5. Any idea what's going on?
private String scale(int org){
tmp = Integer.toString(org);
retArray = new char[6];
for(int i=0; i<=4; i+=2){
tmpsub = tmp.substring(i, i+2); //line 5
int2 = Integer.parseInt(tmpsub);
tmpint = (((float)(int2)/99)*255);
intie = (int)(tmpint);
tmpsub = Integer.toHexString(intie);
subArray = tmpsub.toCharArray();
retArray[i] = subArray[0];
retArray[i+1] = subArray[1]; //String Index Exception on this line
}
retString = "";
for(int i=0; i<retArray.length; i++)
retString+=retArray[i];
return retString;
}
Thanks so much for any help with this problem. Hopefully it's something obvious that I don't see.
The problem is with Integer.toHexString().
If you give it a value that is less than 0x10 (16 in decimal,) you'd get a string of length one as a result, and then subArray[1] would throw an exception.
Related
I don't understand why, but my RSI is always different as Tradingview's RSI.
Is use the same period (14 candles of 15min each), I use the same type of value (closes price), I tried to add the last non closed candle, but I never get the same RSI.
Tradingview RSI code :
//#version=4
study(title="Relative Strength Index", shorttitle="RSI",
format=format.price, precision=2, resolution="")
len = input(14, minval=1, title="Length")
src = input(close, "Source", type = input.source)
up = rma(max(change(src), 0), len)
down = rma(-min(change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
plot(rsi, "RSI", color=#7E57C2)
band1 = hline(70, "Upper Band", color=#787B86)
bandm = hline(50, "Middle Band", color=color.new(#787B86, 50))
band0 = hline(30, "Lower Band", color=#787B86)
fill(band1, band0, color=color.rgb(126, 87, 194, 90), title="Background")
MY code with TA-Lib
MInteger outBegIdx = new MInteger();
MInteger outNbElement = new MInteger();
double[] outReal = new double[array.length-1];
int startIdx = 0;
int endIdx = array.length - 1;
Core core = new Core();
core.rsi(startIdx, endIdx, array, length-1, outBegIdx, outNbElement, outReal);
System.out.println(Arrays.toString(outReal));
return outReal[0];
my custom code without plugin
double av_gain_up_periods = 0;
double av_loss_down_periods = 0;
int gain_count = 0;
int loss_count = 0;
double previous_observation = array[0];
for (int i = 1; i < array.length; i++) {
if (previous_observation <= array[i]) { // if gain
double gain = array[i] - previous_observation;
gain_count++;
av_gain_up_periods += gain;
}
else { // if loss
double loss = previous_observation - array[i];
loss_count++;
av_loss_down_periods += loss;
}
previous_observation = array[i];
}
av_gain_up_periods = av_gain_up_periods/gain_count;
av_loss_down_periods = av_loss_down_periods/loss_count;
// CALCULATE RSI
double relative_strength = av_gain_up_periods/av_loss_down_periods;
double relative_strength_index = 100-(100/(1+relative_strength));
// PRINT RESULT
return relative_strength_index;
I can garantee you that I have 14 closes price and they are the same as Tradingview's. The difference is in the calculation.
Related to this issue
Thanks
I think the problem is in RMA (relative moving average) calculation.it happens because of the unmutual starting point for getting RMA. Different starting point for getting RMA will cause big difference in calculated RSI oppose to tradingview RSI. Tradingview is using Realtime data, hence older data. My suggestion is to start with 1000 klines.
Here is the tradingview formula :
len = input(14, minval=1, title="Length")
src = input(close, "Source", type = input.source)
up = rma(max(change(src), 0), len)
down = rma(-min(change(src), 0), len)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
according to this formula, first you need to get prices and store them somewhere. Closed candles are either gain or loss. After that you have to calculate the change for gain and loss.
Notice : for a closer result get more klines. you need the older data to have a more accurate calculation.( for example 1000 klines)
Now is the time to calculate RMA.
The RMA formula is :
Alpha*source(or as we know, change) + (1-alpha) * previous RMA
Alpha : 1/period(for example 1/14)
At this point we are at the tricky part of calculation. As you can see in the RMA formula, we need the previous RMA to calculate the current one. Assume that we are using 1 hour timeframe and store the klines lets say in an array. Each and every one off array elements has a previous element, hence previous RMA ; But what about the element stored in array[0] ?
It would also be needing previous RMA. Here you will need to calculate SMA(simple moving average).
SMA : the number of prices within a time period is divided by the number of total periods.
The calculated SMA is equal the arrays first member RMA.
Now is the time to calculate RSI. With this method I was able to calculate RSI almost exactly same as tradingview.
Personally, I wrote a bot with C++ to calculate RSI according to tradingview, using Binance API. You can see my code here :
https://github.com/Mina-Jahan/RSIgnal_bot
And I would be appreciated to hear your opinion in order to make my code better if there is a way to reform it.
Thank you.
public ArrayList DCTread(char[] im,int flag,int select, int DC0,int row,int col){
//Input:im is the binary sequence of the host image. I wrote a "byte2char" function to convert that. flag serves as an outside pointer to locate the to-be-decoded chars. DC0 is the DC coeff for the last block.And row,col is simply for debug.
//Main Output:An ArrayList that contains the DCT coeffs,pointer(an int showing how many bits are read in this function)
String rev=new String();char[] DCcode;
ArrayList res = new ArrayList(2);int[][] ac = null; int[][] dc = null;int[][] coeff = new int[8][8];int pointer = 0;
int[] ans;int wordLen;int zeroLen;int diff;int ACnum = 1;int dct;
switch(select){//determine using which two huffman trees.
case(0):ac = a0;dc = d0;break;
case(1):ac = a1;dc = d0;break;
case(16):ac = a0;dc = d1;break;
case(17):ac = a1;dc = d1;break;
}
//DC
ans = T.huffmanDecoder(im,pointer+flag,dc,row,col);
if(ans[0]==-1){
int a1 = T.bin2dec_str(im,pointer+flag,8);int a2 = T.bin2dec_str(im,pointer+flag+8,8);
pointer +=16;//I wish to skip the User Defined Tags by reading its length
int autoLen = T.bin2dec_str(im,pointer+flag,8)*16+T.bin2dec_str(im,pointer+flag+8,8);
pointer +=autoLen*8;
}
ans = T.huffmanDecoder(im,pointer+flag,dc,row,col);
pointer += ans[0];wordLen = ans[1];
diff = T.i_unsignDecoder(T.bin2dec_str(im,pointer+flag,wordLen),wordLen);
coeff[0][0]= DC0 + diff;
pointer += wordLen;DCcode=Arrays.copyOfRange(im, flag, pointer+flag);
//AC
while(ACnum<=63){
ans = T.huffmanDecoder(im,pointer+flag,ac,row,col);
pointer += ans[0];
if(ans[1]==0){//
break;}
zeroLen = (ans[1]&(0xF0))/16;wordLen = ans[1]&(0x0F);
for(int j=0;j<zeroLen;j++){
coeff[zigZag[ACnum][0]][zigZag[ACnum][1]] = 0;
ACnum ++;
}
dct = T.i_unsignDecoder(T.bin2dec_str(im,pointer+flag,wordLen),wordLen);
pointer += wordLen;
coeff[zigZag[ACnum][0]][zigZag[ACnum][1]] = dct;
ACnum ++;
}
res.add(coeff);
res.add(pointer);
res.add(DCcode);
return res;
}
Hi everyone, firstly I'm so glad to welcome you for seeing my tough problem that has bothered me for two days, and gratefully thank you for your time helping me solve this problem. I've been a watcher of StackOverflow for a long time yet it really is my first time posing a problem.
What I want is to read DCT of JPEG in Java without utilizing the libjpeg library (which is written in C++).However I encounter many user defined tags(UDTs) that I find hard to skip using the method I listed above in the algorithm. I'm quite not familiar with UDTs.
AREN'T THEY written with the beginning of "0xFFXX 0x...."(where 0x.... gives the length of this tag)? Your suggestions would be of great help to me. Thanks!
The markers that can be user defined are APPn's and COM. Those markers are followed by lengths in BIG ENDIAN format.
However, I am surprised you are finding "many" such tags. Typically, there will only be one or two in a JPEG stream.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 4 years ago.
Improve this question
I am trying to decrypt an encrypted file with unknown key - the only thing I know about it is that the key is an integer x, 0 <= x < 1010 (i.e. a maximum of 10 decimal digits).
public static String enc(String msg, long key) {
String ans = "";
Random rand = new Random(key);
for (int i = 0; i < msg.length(); i = i + 1) {
char c = msg.charAt(i);
int s = c;
int rd = rand.nextInt() % (256 * 256);
int s2 = s ^ rd;
char c2 = (char) (s2);
ans += c2;
}
return ans;
}
private static String tryToDecode(String string) {
String returnedString = "";
long key;
String msg = reader(string);
for (long i = 0; i <= 999999999; i++) {
System.out.println("decoding message with key + " + i);
key = i;
System.out.println("decoding with key: " + i + "\n" + enc(msg, key));
}
return returnedString;
}
I expect to find the plain text
The program works very slowly, is there any way to make it more efficient?
You can use Parallel Array Operations added in JAVA 8 if you are using Java 8 to achive this.
The best fit for you would be to use Spliterator
public void spliterate() {
System.out.println("\nSpliterate:");
int[] src = getData();
Spliterator<Integer> spliterator = Arrays.spliterator(src);
spliterator.forEachRemaining( n -> action(n) );
}
public void action(int value) {
System.out.println("value:"+value);
// Perform some real work on this data here...
}
I am still not clear about your situation. Here some great tutorials and articles to figure out which parallel array operations of java 8 is going to help you ?
http://www.drdobbs.com/jvm/parallel-array-operations-in-java-8/240166287
https://blog.rapid7.com/2015/10/28/java-8-introduction-to-parallelism-and-spliterator/
First things first: You can't println billions of lines. This will take forever, and it's pointless - you won't be able to see the text as it scrolls by, and your buffer won't save billion of lines so you couldn't scroll back up later even if you wanted to. If you prefer (and don't mind it being 2-3% slower than it otherwise would be), you can output once every hundred million keys, just so you can verify your program is making progress.
You can optimize things by not concatenating Strings inside the loop. Strings are immutable, so the old code was creating a rather large number of Strings, especially in the enc method. Normally I'd use a StringBuilder, but in this case a simple character array will meet our needs.
And there's one more thing we need to do that your current code doesn't do: Detect when we have the answer. If we assume that the message will only contain characters from 0-127 with no Unicode or extended ASCII, then we know we have a possible answer when the entire message contains only characters in this range. And we can also use this to further optimize, as we can then immediately discard any message that has a character outside of this range. We don't even have to finish decoding it and can move on to the next key. (If the message is of any length, the odds are that only one key will produce a decoded message with characters in that range - but it's not guaranteed, which is why I do not stop when I get to a valid message. You could probably do that, though.)
Due to the way random numbers are generated in Java, anything in the seed above 32 bits is not used by the encoding/decoding algorithm. So you only need to go up to 4294967295 instead of 9999999999. (This also means the key that was originally used to encode the message might not be the key this program uses to decode it, since 2-3 keys in the 10 digit range will produce the same encoding/decoding.)
private static String tryToDecode4(String msg) {
String returnedString = "";
for (long i=0; i<=4294967295l; i++)
{
if (i % 100000000 == 0) // This part is just to see that it's making progress. Remove if desired for a small speed gain.
System.out.println("Trying " + i);
char[] decoded = enc4(msg, i);
if (decoded == null)
continue;
returnedString = String.valueOf(decoded);
System.out.println("decoding with key: " + i + " " + returnedString);
}
return returnedString;
}
private static char[] enc4(String msg, long key) {
char[] ansC = new char[msg.length()];
Random rand = new Random(key);
for(int i=0;i<msg.length();i=i+1)
{
char c = msg.charAt(i);
int s = c;
int rd = rand.nextInt()%(256*256);
int s2 = s^rd;
char c2 = (char)(s2);
if (c2 > 127)
return null;
ansC[i] = c2;
}
return ansC;
}
This code finished running in a little over 3 minutes on my machine, with a message of "Hello World".
This code will not work well for very short messages (3-4 characters or less.) It will not work if the message contains Unicode or extended ASCII, although it could easily be modified to do so if you know the range of characters that might be in the message.
QUESTION:
How can I read the string "d6+2-d4" so that each d# will randomly generate a number within the parameter of the dice roll?
CLARIFIER:
I want to read a string and have it so when a d# appears, it will randomly generate a number such as to simulate a dice roll. Then, add up all the rolls and numbers to get a total. Much like how Roll20 does with their /roll command for an example. If !clarifying {lstThen.add("look at the Roll20 and play with the /roll command to understand it")} else if !understandStill {lstThen.add("I do not know what to say, someone else could try explaining it better...")}
Info:
I was making a Java program for Dungeons and Dragons, only to find that I have come across a problem in figuring out how to calculate the user input: I do not know how to evaluate a string such as this.
I theorize that I may need Java's eval at the end. I do know what I want to happen/have a theory on how to execute (this is more so PseudoCode than Java):
Random rand = new Random();
int i = 0;
String toEval;
String char;
String roll = txtField.getText();
while (i<roll.length) {
check if character at i position is a d, then highlight the numbers
after d until it comes to a special character/!aNumber
// so if d was found before 100, it will then highlight 100 and stop
// if the character is a symbol or the end of the string
if d appears {
char = rand.nextInt(#);
i + #'s of places;
// so when i++ occurs, it will move past whatever d# was in case
// d# was something like d100, d12, or d5291
} else {
char = roll.length[i];
}
toEval = toEval + char;
i++;
}
perform evaluation method on toEval to get a resulting number
list.add(roll + " = " + evaluated toEval);
EDIT:
With weston's help, I have honed in on what is likely needed, using a splitter with an array, it can detect certain symbols and add it into a list. However, it is my fault for not clarifying on what else was needed. The pseudocode above doesn't helpfully so this is what else I need to figure out.
roll.split("(+-/*^)");
As this part is what is also tripping me up. Should I make splits where there are numbers too? So an equation like:
String[] numbers = roll.split("(+-/*^)");
String[] symbols = roll.split("1234567890d")
// Rough idea for long way
loop statement {
loop to check for parentheses {
set operation to be done first
}
if symbol {
loop for symbol check {
perform operations
}}} // ending this since it looks like a bad way to do it...
// Better idea, originally thought up today (5/11/15)
int val[];
int re = 1;
loop {
if (list[i].containsIgnoreCase(d)) {
val[]=list[i].splitIgnoreCase("d");
list[i] = 0;
while (re <= val[0]) {
list[i] = list[i] + (rand.nextInt(val[1]) + 1);
re++;
}
}
}
// then create a string out of list[]/numbers[] and put together with
// symbols[] and use Java's evaluator for the String
wenton had it, it just seemed like it wasn't doing it for me (until I realised I wasn't specific on what I wanted) so basically to update, the string I want evaluated is (I know it's a little unorthodox, but it's to make a point; I also hope this clarifies even further of what is needed to make it work):
(3d12^d2-2)+d4(2*d4/d2)
From reading this, you may see the spots that I do not know how to perform very well... But that is why I am asking all you lovely, smart programmers out there! I hope I asked this clearly enough and thank you for your time :3
The trick with any programming problem is to break it up and write a method for each part, so below I have a method for rolling one dice, which is called by the one for rolling many.
private Random rand = new Random();
/**
* #param roll can be a multipart roll which is run and added up. e.g. d6+2-d4
*/
public int multiPartRoll(String roll) {
String[] parts = roll.split("(?=[+-])"); //split by +-, keeping them
int total = 0;
for (String partOfRoll : parts) { //roll each dice specified
total += singleRoll(partOfRoll);
}
return total;
}
/**
* #param roll can be fixed value, examples -1, +2, 15 or a dice to roll
* d6, +d20 -d100
*/
public int singleRoll(String roll) {
int di = roll.indexOf('d');
if (di == -1) //case where has no 'd'
return Integer.parseInt(roll);
int diceSize = Integer.parseInt(roll.substring(di + 1)); //value of string after 'd'
int result = rand.nextInt(diceSize) + 1; //roll the dice
if (roll.startsWith("-")) //negate if nessasary
result = -result;
return result;
}
Ok Here is my example text... everything is
THEPONDIS15AWAYLOOKATTHOSEBASS5POUNDERSWELLLITATNIGHTALLAROUNDQUIETSEMICOUNTRYAREASTILLMOREBUTCALLMENORENTALNOLEASEANDPLEASEWENEEDNOREALTORSASMYWIFEDOES3176665440ANDCANNOTKEEPALLTHEMAINTANCEOFABIGHOUSEWANNAGOSOUTHTHANKSCALLMETHANKS
As you can see the Call and the phone number are within so far of eachother within 60 chars or so. So I been trying to right an expression to find this, determine that CALL is within 60 chars or so and then pull the phone number if it is..
I know that I would need something like...
Pattern p11 = Pattern.compile("[0-9]{11}");
Pattern p10 = Pattern.compile("[0-9]{10}");
Pattern p7 = Pattern.compile("[0-9]{7}");
In order to determine if its possibly an actual phone number since it could be 13173333333 or just 3173333333 or just 3333333
What about the rest? I know I would probably have to do a type of substring or something, but Its giving me a lot more difficulty then I thought it would.
I tried doing this...
String PHONENUMBER = "";
Pattern p11 = Pattern.compile("[0-9]{11}");
Pattern p10 = Pattern.compile("[0-9]{10}");
Pattern p7 = Pattern.compile("[0-9]{7}");
Matcher m11 = p11.matcher(Number);
Matcher m10 = p10.matcher(Number);
Matcher m7 = p7.matcher(Number);
String Call = "CALL";
String Text = "TEXT";
String Message = "MESSAGE";
if (Number.contains(Call)) {
int Numindex = Number.indexOf(Call);
int low = Numindex - 30;
int high = Numindex + 35;
if (low < 0) {
low = 0;
}
if (high > Number.length()) {
high = Number.length();
}
String extract = Number.substring(low, high);
m11 = p11.matcher(extract);
m10 = p10.matcher(extract);
m7 = p7.matcher(extract);
if (m11.find() == true) {
PHONENUMBER = m11.group();
} else if (m10.find() == true) {
PHONENUMBER = m10.group();
} else if (m7.find() == true) {
PHONENUMBER = m7.group();
}
But for some reason its not working out for me
EDIT #1 Requested for Original Text....
The Pond is 15' away- look at those bass- 5 Pounders-- well lit at night all around- quiet Semi Country area...still more but Ca ll me- NO RENTAL/No Lease and Please- we need NO Realtors as my Wife does 317 6 6.6-54.4 0 and cannot keep all the maintance of a big House- wanna go South Thanks call me!Call Me Thanks!
As you can see from the original text, it only makes sense to remove the spaces and all special characters then just do a simple expression comparison to find the phone number, then just find if the word "call" is within 60 chars. Obviously this isn't the ONLY paragraph there are hundreds more.
I'll be honest this seems like you are doing it in an extremely difficult way. However here is an idea on how you could go about doing it.
First get the range you want to check for the number let's say it's 0(low)-15(high)
then write a for loop to loop through that range of characters. The below code is an example of how you could set it up to loop through the section of the string you want checking the characters along the way to see if it matches a phone number. Take in mind this doesn't take in account reaching the end of the String to soon which would result in an index out of bounds exception nor does it take in account if it is too large of a number but I will let you figure those things out.
String number = "123HEY1234567890HOWIS";
int realNum = 0; //if this hits exactly 10 then it is a real phone number
int low = 0;
int high = number.length();
for(int i = low; i < high;i++){
//check if the current char is a number
if(number.substring(i, i + 1).matches("[0-9]")){
//if yes then increment
realNum++;
System.out.println(realNum);
//checks if realNum is 10 and makes sure that the next char isn't a number also
if(realNum == 10){
low = i - 9;
high = i;
System.out.println("match");
break;
}
}else{
//if no then reset the checker back to 1
realNum = 0;
}
}
System.out.println("All Done");
Hopefully this at least gets you on the right path.
I would use https://github.com/googlei18n/libphonenumber and not regex for finding phone numbers. The library works as you would expect
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Iterable<PhoneNumberMatch> numbers = phoneUtil.findNumbers(text, Locale.US.getCountry());
List<String> data = new ArrayList<>();
numbers.forEach(number -> {
String s = number.rawString();
// your phone numbers
});