new to programming i know i'm doing something that's probably really obviously wrong to do with passing or using the wrong variables but i just can't work out what.
Here is my code:
public class CameraViewActivity extends Activity implements
SurfaceHolder.Callback, OnLocationChangedListener, OnAzimuthChangedListener {
private double mAzimuthReal = 0;
private double mAzimuthTheoretical = 0;
private static double AZIMUTH_ACCURACY = 5;
private double mMyLatitude = 0;
private double mMyLongitude = 0;
private List<Double> calculateAzimuthAccuracy(double azimuth) {
double minAngle = azimuth - AZIMUTH_ACCURACY;
double maxAngle = azimuth + AZIMUTH_ACCURACY;
List<Double> minMax = new ArrayList<Double>();
#Override
public void onAzimuthChanged(float azimuthChangedFrom, float azimuthChangedTo) {
mAzimuthReal = azimuthChangedTo;
mAzimuthTheoretical = calculateTheoreticalAzimuth();
pointerIcon = (ImageView) findViewById(R.id.icon);
double minAngle = calculateAzimuthAccuracy(mAzimuthTheoretical).get(0);
double maxAngle = calculateAzimuthAccuracy(mAzimuthTheoretical).get(1);
if (isBetween(minAngle, maxAngle, mAzimuthReaal) {
pointerIcon.setVisibility(View.VISIBLE);
}
else {
pointerIcon.setVisibility(View.INVISIBLE);
}
updateDescription();
}
Thanks for reading
Use
isRange(mMyLatitude, mMyLongitude, mPoi.getPoiLatitude(), mPoi.getPoiLongitude)
instead of
isRange(MyLatitude, MyLongitude, MpoiLatitude, MpoiLongitude)
FYI, its better to use small letter for naming variable.
In this function you need to pass as paramters either two locations and use their coordinates in the function inRange or you pass four coordinates and use them.
public void onAzimuthChanged(float azimuthChangedFrom, float azimuthChangedTo) {
mAzimuthReal = azimuthChangedTo;
mAzimuthTheoretical = calculateTheoreticalAzimuth();
pointerIcon = (ImageView) findViewById(R.id.icon);
double minAngle = calculateAzimuthAccuracy(mAzimuthTheoretical).get(0);
double maxAngle = calculateAzimuthAccuracy(mAzimuthTheoretical).get(1);
if (isBetween(minAngle, maxAngle, mAzimuthReal) && isRange(MyLatitude, MyLongitude, MpoiLatitude, MpoiLongitude)) {
pointerIcon.setVisibility(View.VISIBLE);
}
else {
pointerIcon.setVisibility(View.INVISIBLE);
}
updateDescription();
}
This has no meaning
isRange(MyLatitude, MyLongitude, MpoiLatitude, MpoiLongitude);
One more thing, adapt a professional naming criteria. Giving your attributes names that start with capital letters is quite MEH.
Related
I cannot understand the meaning of the code. Can you give me a help to translate the code into Java?
private var framePeriodMs: Long = 0
var frameRate: Float = Float.MAX_VALUE
set(value) {
this.framePeriodMs = (1000 / value).toLong()
log.info("framePeriodMs: $framePeriodMs")
field = value
}
Thank you very much...
This should be about right (though my Java's rusty):
private long framePeriodMs = 0;
private float frameRate = Float.MAX_VALUE;
public float getFrameRate() {
return frameRate;
}
public void setFrameRate(float newFrameRate) {
this.framePeriodMs = (long)(1000 / newFrameRate);
log.info("framePeriodMs: " + framePeriodMs);
this.frameRate = newFrameRate;
}
The value coming into the set(...) { ... } function is just like a parameter into a Java setter.
I don't want to solve an equation and my question is not about Graphs and Trees Data Structures. I am trying to generate Data Points for graph from an equation given by user. I want efficient algorithm, easy to use and easy to maintain data structures. I have two solutions in mind
1: This is trivial and I have seen in many Applications.
String expr = "2*x+3*x";
Evaluator evaluator = new Evaluator();//I have this class
for (int i = start; i < end; i += step)
{
evaluator.setConstant("x", i);
double ans = evaluator.evaluate(expr);
}
This is very slow because each time every step is repeated like tokenzing, verifying, conversion to RPN, preparing stacks and queues and at last result calculation. The possible solution to this problem is somehow caching all stacks and queues but after that a comparison would be required between current expression and previous expression to use last stored state.
2: Currently I am developing second solution. The purpose of this is efficiency and would be used in Symbolic calculation in future.
So far my implementation
Variable.java
import java.text.DecimalFormat;
public class Variable
{
private final double pow;
private final double coefficient;
private final String symbol;
public Variable(String symbol)
{
this.symbol = symbol;
this.pow = 1.0;
this.coefficient = 1.0;
}
public Variable(String symbol, double coefficient, double pow)throws IllegalArgumentException
{
if (coefficient == 0.0)throw new IllegalArgumentException("trying to create variable with coefficient 0");
if (pow == 0.0)throw new IllegalArgumentException("trying to create variable with exponent 0");
this.symbol = symbol;
this.pow = pow;
this.coefficient = coefficient;
}
public final String getSymbol()
{
return this.symbol;
}
public final double getPow()
{
return this.pow;
}
public final double getCoefficient()
{
return this.coefficient;
}
#Override
public String toString()
{
StringBuilder builder = new StringBuilder();
DecimalFormat decimalFormat = new DecimalFormat("#.############");
if (coefficient != 1.0)builder.append(decimalFormat.format(this.coefficient));
builder.append(this.symbol);
if (this.pow != 1.0)builder.append("^").append(decimalFormat.format(this.pow));
return builder.toString();
}
/*
* Stub Method
* Generate some unique hash code
* such that chances of key collision
* become less and easy to identify
* variables with same power and same
* symbol*/
#Override
public int hashCode()
{
return 0;
}
}
Equation.java
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
public class Equation
{
private final ArrayList<Boolean> operations;
private final HashMap<String, Variable> variableHashMap;
private int typesOfVariables;
public Equation(Variable variable)
{
this.variableHashMap = new HashMap<>();
this.operations = new ArrayList<>();
this.typesOfVariables = 1;
this.variableHashMap.put(variable.getSymbol(), variable);
}
/*Stub Method*/
public void addVariable(Variable variable, boolean multiply)
{
/*
* Currently not covering many cases
* 1: Add two variables which have same name
* and same pow.
* 2: variable which are wrapped inside functions e.g sin(x)
* and many other.*/
if (multiply && variableHashMap.containsKey(variable.getSymbol()))
{
Variable var = variableHashMap.get(variable.getSymbol());
Variable newVar = new Variable(var.getSymbol(), var.getCoefficient() * variable.getCoefficient(), var.getPow() + variable.getPow());
/*
* Collision chances for variables with same name but
* with different powers*/
this.variableHashMap.replace(var.getSymbol(), newVar);
}
else
{
++this.typesOfVariables;
this.variableHashMap.put(variable.getSymbol(), variable);
}
this.operations.add(multiply);
}
/*Stub Method
*Value for every variable at any point will be different*/
public double solveFor(double x)
{
if (typesOfVariables > 1)throw new IllegalArgumentException("provide values for all variables");
Iterator<HashMap.Entry<String, Variable>> entryIterator = this.variableHashMap.entrySet().iterator();
Variable var;
double ans = 0.0;
if (entryIterator.hasNext())
{
var = entryIterator.next().getValue();
ans = var.getCoefficient() * Math.pow(x, var.getPow());
}
for (int i = 0; entryIterator.hasNext(); i++)
{
var = entryIterator.next().getValue();
if (this.operations.get(i))ans *= var.getCoefficient() * Math.pow(x, var.getPow());
else ans += var.getCoefficient() * Math.pow(x, var.getPow());
}
return ans;
}
#Override
public String toString()
{
StringBuilder builder = new StringBuilder();
Iterator<HashMap.Entry<String, Variable>> entryIterator = this.variableHashMap.entrySet().iterator();
if (entryIterator.hasNext())builder.append(entryIterator.next().getValue().toString());
Variable var;
for (int i = 0; entryIterator.hasNext(); i++)
{
var = entryIterator.next().getValue();
if (this.operations.get(i))builder.append("*").append(var.toString());
else builder.append(var.toString());
}
return builder.toString();
}
}
Main.java
class Main
{
public static void main(String[] args)
{
try
{
long t1 = System.nanoTime();
Variable variable = new Variable("x");
Variable variable1 = new Variable("x", -2.0, 1.0);
Variable variable2 = new Variable("x", 3.0, 4.0);
Equation equation = new Equation(variable);
equation.addVariable(variable1, true);//2x+x
equation.addVariable(variable2, true);
for (int i = 0; i < 1000000; i++)equation.solveFor(i);//Calculate Million Data Points
long t2 = System.nanoTime();
System.out.println((t2-t1)/1000/1000);
System.out.println(equation.toString());
}
catch (Exception e)
{
System.out.println("Error: " + e.getMessage());
}
}
}
Am I going in right direction?
Is there any commonly used Algorithm for this problem?
My main goal is efficiency, code cleanness and code maintainability.
Note: I am not native English speaker so please ignore any grammatical mistake.
Thanks.
I do not see any problem with your first code. Yes may be at every step your code "repeat like tokenzing, verifying, conversion to RPN, preparing stacks and queues and at last result calculation", but in the end all of this is just linear number of steps. So I fail to see how it can make it really slow.
One of the biggest screens I have seen was 2560x1440 pixels, which means that most of the time you would need less than 2500 points to draw your graph there.
If you point is code cleanness and code maintainability, then most probably a code consisting of 5 lines is better than the code consisting of 200.
I am getting my speed from the gps using location.speed() function and the value is getting stored in nCurrentSpeed.
Should i store the nCurrentSpeed value in an Array to get the average speed when the app has stopped? How do i do it?
#Override
public void onLocationChanged(Location location) {
TextView dis =(TextView)findViewById(R.id.distance);
TextView time1 =(TextView)findViewById(R.id.time);
Typeface myTypeface = Typeface.createFromAsset(getAssets(), "SPEEDOFONT.TTF");
text2 = (TextView) findViewById(R.id.text2);
text2.setTypeface(myTypeface);
float speed,time, distance;
if (location == null) {
text2.setText("-.- km/h");
} else {
float nCurrentSpeed = location.getSpeed();
speed = (float) (nCurrentSpeed * 3.6);
text2.setText(String.format("%.2f km/h", speed));
time =location.getTime();
time1.setText("" +time);
distance = speed*time;
dis.setText(String.format("%.2f m/s", distance));
}
}
It may not be spot on to the actual (very specific) question, but you could also use DoubleSummaryStatistics: You can create an instance of this class, then let it accept one value after the other, and finally get the average without doing manual computations - and by the way, you get the computation of the minimum and maximum for free.
private final DoubleSummaryStatistics stats = new DoubleSummaryStatistics();
public void onLocationChanged(Location location)
{
...
float speed = ...;
stats.accept(speed);
}
void printSummary()
{
double average = stats.getAverage();
double min = stats.getMin();
double max = stats.getMax();
...
}
EDIT:
In case you don't use Java 8 yet, you can do
private final List<Float> speeds = new ArrayList<Float>();
public void onLocationChanged(Location location)
{
...
float speed = ...;
speeds.add(speed);
}
private float computeAverage(List<Float> values)
{
float sum = 0;
for (Float v : values)
{
sum += v;
}
return sum / values.size();
}
void printSummary()
{
double average = computeAverage(speeds);
...
}
(Similar to what #AndrewTobilko originally proposed)
I want to print the three values of each axes(scaledX , scaledY, scaledZ) of accelerometer in three TextView.
Can somebody help me?
thanks.
CODE:
MainActivity.java.
public class MainActivity extends Activity implements BluetoothAdapter.LeScanCallback {
private TextView mAccelerometerx, mAccelerometery, mAccelerometerz;
mAccelerometerx =(TextView) findViewById(R.id.ejex);
mAccelerometery =(TextView) findViewById(R.id.ejey);
mAccelerometerz =(TextView) findViewById(R.id.ejez);
private void updateAccelerometerValue(BluetoothGattCharacteristic characteristic ){
double accelerometerx = SensorTagData.extractAccelerometer(characteristic, mAccelerometerx);
double accelerometery = SensorTagData.extractAccelerometer(characteristic, mAccelerometery);
double accelerometerz = SensorTagData.extractAccelerometer(characteristic, mAccelerometerz);
mAccelerometerx.setText(String.format("%.4f", accelerometerx));
mAccelerometery.setText(String.format("%.4f", accelerometery));
mAccelerometerz.setText(String.format("%.4f", accelerometerz));
}
}
SensorData.java
public class SensorData {
public static double [] extractAccelerometer(BluetoothGattCharacteristic c) {
Integer x = c.getIntValue(FORMAT_SINT8, 0);
Integer y = c.getIntValue(FORMAT_SINT8, 1);
Integer z = c.getIntValue(FORMAT_SINT8, 2) * -1;
double scaledX = x / 64.0;
double scaledY = y / 64.0;
double scaledZ = z / 64.0;
return new double[] {scaledX, scaledY, scaledZ};
}
}
private void updateAccelerometerValue(BluetoothGattCharacteristic characteristic ){
double accelerometerx = SensorTagData.extractAccelerometer(characteristic, mAccelerometerx);
double accelerometery = SensorTagData.extractAccelerometer(characteristic, mAccelerometery);
double accelerometerz = SensorTagData.extractAccelerometer(characteristic, mAccelerometerz);
mAccelerometerx.setText(String.format("%.4f", accelerometerx)); //ERROR HERE
mAccelerometery.setText(String.format("%.4f", accelerometery)); //ERROR HERE
mAccelerometerz.setText(String.format("%.4f", accelerometerz)); //ERROR HERE
}
ERROR Type
The method extractAccelerometer(BluetoothGattCharacteristic) in the type SensorTagData is not applicable for the arguments (BluetoothGattCharacteristic, TextView)
I know I am giving more than two parameters, but if I delete "accelerometerx", "accelerometery" , "accelerometerz" the error disappears but I suppose will not see anything.
I can convert from fahrenheit to celcius, but not the other way around. I have attached the code below. Hopefully it's enough to see what is going on.
public void actionPerformed(ActionEvent arg0) {
double temps = 0, temp1 = 0;
String instrings;
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temps = Double.parseDouble(instrings);
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temp1 = Double.parseDouble(instrings);
if(arg0.getActionCommand().equals("C")){
temps = (( temps * 9)/5+32);
DecimalFormat formatters = new DecimalFormat("#,###,###.###");
results.setText(""+formatters.format(temps));
}
else if(arg0.getActionCommand().equals("F"));
{
temp1 = (((temps - 32)/9)*5);
DecimalFormat formatters = new DecimalFormat("#,###,###.###");
results.setText(""+formatters.format(temp1));
}
}
Put a
System.out.println(arg0.getActionCommand());
in your method, and supposedly you will see that it is not "C" when using the Celsius button.
Generally, look at the console to see if there are any error messages around.
Another idea: You are using two double variables temps and temp1, parsing the instrings into both of them, and setting then one of them to the result. Why so complicated?
In general, I would recommend to not use the getActionCommand() method, but to give each button an own ActionListener. You can use an anonymous class for this. As both cases do almost the same, use two subclasses of a inner (or even local) class here:
abstract class ConversionListener implement ActionListener {
DecimalFormat formatter = new DecimalFormat("#,###,###.##");
public void actionPerformed(ActionEvent e) {
String input = temp.getText();
if (input.equals("")) {
input = "0";
temp.setText(input);
}
double number = Double.parseDouble(input);
results.setText(formatter.format(convert(number)));
}
/** to implement by subclasses */
abstract double convert(double number);
}
celsiusToFahrenheit.addActionListener(new ConversionListener() {
double convert(double celsius) {
return number * 9 / 5 + 32;
}
});
fahrenheitToCelsius.addActionListener(new ConversionListener() {
double convert(double fahrenheit) {
return (fahrenheit - 32) / 9 * 5;
}
});
Not sure what you are having trouble with but here is how to convert Celsius to Fahrenheit in Java.
float celsius = celsius value
float c=Float.parseFloat(celsius);
float f = 32 + 9*c/5;
Change from
temp1 = (((temps - 32)/9)*5);
to
temp1 = (((temps - 32)*5)/9);
instead.
On this part:
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temps = Double.parseDouble(instrings);
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temp1 = Double.parseDouble(instrings);
Am I missing something or is temps and temp1 both getting set to the same value? Or is it possible that between the temps assignment the temp.getText() could return a different value?
If it's the same, start by rewriting it to
instrings = temp.getText();
if(instrings.equals(""))
{
instrings = "0";
temp.setText("0");
}
temps = Double.parseDouble(instrings);
temp1 = Double.parseDouble(instrings);
or even temp1 = temps
Also, some better naming of variables might be easier, temps, temp and temp1 are all very similar. One appears to be text from a control and the other 2 are numeric values.
Even names like 'inputTemperature' and 'calculatedTemperature' go a long way to making the code more readable.
This doesn't help solve your problem, but might help debugging in the future.