Fill missing values on a table - java

I have a list of dates and prices:
Date Price
1/3/2000 10.00
1/5/2000 10.45
1/7/2000 10.25
... ...
I have a separate list of dates with all dates:
Date
1/1/2000
1/2/2000
1/3/2000
...
I need to have them combined so that the prior price is filled in for the dates that are missing prices:
Date Price
1/1/2000 10.00
1/2/2000 10.00
1/3/2000 10.00
1/4/2000 10.00
1/5/2000 10.45
1/6/2000 10.45
1/7/2000 10.25
... ...
I am currently trying to loop through array lists holding the data but can't line the dates up correctly, especially at the beginning and end. I am using Java/Mysql/JDBC right now but am open to R also. Thanks for any suggestions.

Thanks to everyone for your help. Here's what I ended up doing:
-I created a list of all indexes where the dates matched.
-I then inserted the prices into an array with the same number of elements as the full time list.
-I then created 3 loops, one for the elements before the first matching time, one for the elements after the last matching element and finally one for everything in between.
-These three filled in the prices that were missing.
Just though I'd share. Thanks for all your help.
public static void checkLengths(ArrayList<String> masterTimes, ArrayList<String> testTimes, ArrayList<Double> prices){
ArrayList<Double> temp = new ArrayList<Double>();
ArrayList<Integer> matches = new ArrayList<Integer>();
Double[] temp2 = new Double [masterTimes.size()];
int mt = masterTimes.size();
int tt = testTimes.size();
if(mt == tt){
return;
}else{
int mast = 0;
int test = 0;
String mt1 = masterTimes.get(0);
String tt1 = testTimes.get(0);
test = 0;
for(int i = 0; i < masterTimes.size(); i++){
mt1 = masterTimes.get(i);
tt1 = testTimes.get(test);
System.out.println(" | mt1: " + mt1 + " | tt1: " + tt1);
if(mt1.equals(tt1)){
matches.add(i);
System.out.println("Inserting: " + i);
if(test < testTimes.size()){
test++;
}
if(test == testTimes.size()){
break;
}
}
}
System.out.println("Matches:");
printAL(matches);
// puts in known prices.
for(int i = 0; i < matches.size(); i++){
int g = matches.get(i);
temp2[g] = prices.get(i);
}
System.out.println("FirstPrices:");
printAR(temp2);
// Finds index of first and last matching times.
int matcher1 = matches.get(0);
int ind = matches.size() - 1;
int matcher2 = matches.get(ind);
System.out.println("Matcher1:" + matcher1 + " | Matcher2: " + matcher2);
// If a price is empty/null, it puts the prior price in it.
for(int i = matcher1; i < matcher2; i ++){
System.out.println(i + " | " + temp2[i]);
if(temp2[i] == null){
System.out.println(temp2[i] + " | " + temp2[i-1]);
temp2[i] = temp2[i-1];
}
}
System.out.println("SecondPrices:");
printAR(temp2);
// Deals with start.
for(int i = matcher1; i >= 0; i--){
if(temp2[i] == null){
temp2[i] = temp2[i+1];
}
}
System.out.println("ThirdPrices:");
printAR(temp2);
// Deals with end.
for(int i = matcher2; i < temp2.length; i++){
if(temp2[i] == null){
temp2[i] = temp2[i-1];
}
}
System.out.println("FourthPrices:");
printAR(temp2);
prices.clear();
System.out.println("Final Check:");
for (int i = 0; i < masterTimes.size(); i++){
System.out.println(i + " | " + masterTimes.get(i) + " | " + temp2[i]);
}
}
}

It is difficult to help without looking at the code but it seems like your indexes are not matching up or something is wrong with your looping logic.
Consider using a HashTable or a HashMap using the date strings as keys and price as values.
Loop through your date range one day at a time look up the price in the HashTable, if not found then use the previous price.

This sort of problem does take a bit of doing to do correctly. Sometimes using a flow chart helps if you get stuck.
Try using the following sample code:
import java.sql.*;
import java.util.*;
public class FillDates
{
public static void fillUnknownDates(Connection c) throws SQLException
{
// Loads in a Vector of Strings of all the dates
Statement state = c.createStatement();
ResultSet results = state.executeQuery("SELECT d FROM Dates ORDER BY d;");
Vector<String> dates = new Vector<String>();
while (results.next())
{
dates.add(results.getString("d"));
}
// Load in a list of all date/price combinations
Vector<DatePrice> pairs = new Vector<DatePrice>();
state = c.createStatement();
results = state.executeQuery("SELECT d, p FROM DatePrices ORDER BY d;");
while (results.next())
{
pairs.add(new DatePrice(results.getString("d"), results.getString("p")));
}
// Now go through the two lists and add missing prices
state = c.createStatement();
int dateIndex = 0;
DatePrice last = pairs.get(0), current;
for (int pairIndex = 1; pairIndex < pairs.size(); pairIndex++)
{
current = pairs.get(pairIndex);
while (dateIndex < dates.size() && dates.get(dateIndex).compareTo(current.getDate()) < 0)
{
// Batch things up so it takes less time to run
state.addBatch("INSERT INTO DatePrices VALUES (\""+dates.get(dateIndex)+"\", \""+current.getPrice+"\");");
dateIndex ++;
}
last = current;
}
state.executeBatch();
}
// A convenience class
public static class DatePrice
{
private String date, price;
public DatePrice(String date, String price)
{
this.date = date;
this.price = price;
}
public String getDate()
{
return date;
}
public String getPrice()
{
return price;
}
}
}
Note that it's not complete, and you'll need to change the names of your tables and columns before trying it out.

Okay... I just shooting at it while being on the fon :)
In MySQL, let's assume you got two tables, dates_prices and all_dates. Then LEFT JOIN them on dates and order them by date.
If you use R and MySQL you can use the RMySQL package to load the resulting table to R.
In R you can convert the dates to POSIX with as.POSIXlt. You also might want to use the lagfunction in R (but I am not sure yet if that helps with lags of varying spans).
Apart from that you could use R's ´sqldf` package if you want to try with "plain" R but want to use SQL functionality. If you post some reproducible code to set up the data.. I could try to the give something more concrete back.
EDIT:
The impute package might be what you really looking for... see also here

Here is an R solution.
Uncomment the two install.packages lines if you don't have those packages already installed. Also textConnection(Lines1) and textConnection(Lines2) are just to keep the example self contained and in reality would be replaced with something like "myfile1.dat" and "myfile2.dat" assuming the data is in those files.
It reads in the data creating zoo object z and a Date vector dt. It then merges z with a zero width zoo object (i.e. it has dates but no data) whose date index is made from dt. na.locf (last observation carried forward) fills out the missing values in reverse order since fromLast = TRUE
Lines1 <- "Date Price
1/3/2000 10.00
1/5/2000 10.45
1/7/2000 10.25"
Lines2 <- "Date
1/1/2000
1/2/2000
1/3/2000"
# install.packages("zoo")
# install.packages("chron")
library(zoo)
library(chron)
z <- read.zoo(textConnection(Lines1), header = TRUE, FUN = as.chron)
dt <- as.chron(scan(textConnection(Lines2), skip = 1, what = ""))
na.locf(merge(z, zoo(, dt)), fromLast = TRUE)
The result is:
> na.locf(merge(z, zoo(, dt)), fromLast = TRUE)
01/01/00 01/02/00 01/03/00 01/05/00 01/07/00
10.00 10.00 10.00 10.45 10.25
There are three vignettes (PDF documents) that come with the zoo package and R News 4/1 Help Desk article has info and references on dates.

Related

how to verify array list WebElement in selenium greater and lowest value

website is dark sky and I want to verify current temp is greater or less than temps from timeline. I used array list. I need to get current temp and compare it with them. Thank you. I couldn’t do that. Do u have any idea for this. Thnx.
ArrayList<WebElement> list = new ArrayList<>(SharedSD.getDriver( ).findElements(greaterOrLess));
DarkSky considered for test:
Python Script on darksky:
Just converted the python code to java
driver.get("https://darksky.net/forecast/40.7127,-74.0059/us12/en");
String currentTemp = driver.findElement(By.cssSelector(".summary.swap")).getText();
System.out.println("Current Temp:" + currentTemp);
List<WebElement> tempsInTimeLine = driver.findElements(By.cssSelector(".temps span:last-child"));
int temp = Integer.parseInt(currentTemp.substring(0, 2));
int highestInTimeLine = temp;
int lowestInTimeLine = temp;
for (WebElement tempInTime: tempsInTimeLine) {
String sLIneTemp = tempInTime.getText();
int lineTemp = Integer.parseInt(sLIneTemp.substring(0, 2));
if (lineTemp > highestInTimeLine){
highestInTimeLine = lineTemp;
}
if (lineTemp < lowestInTimeLine ){
lowestInTimeLine = lineTemp;
}
}
System.out.println("Highest Temp:" + Integer.toString(highestInTimeLine));
System.out.println("Lowest Temp:" + Integer.toString(lowestInTimeLine ));

nearest neighbor algorithm copy element (city) to output array java

So I have a program written so far that reads in a csv file of cities and distances in the following format:
Alaska Mileage Chart,Anchorage,Anderson,Cantwell,
Anchorage,0,284,210,
Anderson,284,0,74,
Cantwell,210,74,0,
So the algorithm works and outputs the cities in the order they should be visited following the shortest path using the nearest neighbor algorithm always starting with Anchorage as the city of origin or starting city.
Using this data, the example output for the algorithm is: 1,3,2. I have ran this with a 27 element chart and had good results as well. I am using this small one for writing and debugging purposes.
Ideally the output I am looking for is the Name of the City and a cumulative milage.
Right now I am having working on trying to get the cities into an array that I can print out. Help with both parts would be appreciated or help keeping in mind that is the end goal is appreciated as well.
My thought was that ultimately I may want to create an array of {string, int}
so my output would look something like this..
Anchorage 0
Cantwell 210
Anderson 284
I am able to set the first element of the array to 1, but can not get the 2nd and 3rd element of the new output array to correct
This is the code I am having a problem with:
public class TSPNearestNeighbor {
private int numberOfNodes;
private Stack<Integer> stack;
public TSPNearestNeighbor()
{
stack = new Stack<>();
}
public void tsp(int adjacencyMatrix[][])
{
numberOfNodes = adjacencyMatrix[1].length;
// System.out.print(numberOfNodes);
// System.out.print(Arrays.deepToString(adjacencyMatrix));
int[] visited = new int[numberOfNodes];
// System.out.print(Arrays.toString(visited));
visited[1] = 1;
// System.out.print(Arrays.toString(visited));
stack.push(1);
int element, dst = 0, i;
int min = Integer.MAX_VALUE;
boolean minFlag = false;
System.out.print(1 + "\n");
//System.arraycopy(arr_cities, 0, arr_final, 0, 1); // Copies Anchorage to Pos 1 always
//System.out.print(Arrays.deepToString(arr_final)+ "\n");
while (!stack.isEmpty())
{
element = stack.peek();
i = 1;
min = Integer.MAX_VALUE;
while (i <= numberOfNodes-1)
{
if (adjacencyMatrix[element][i] > 1 && visited[i] == 0)
{
if (min > adjacencyMatrix[element][i])
{
min = adjacencyMatrix[element][i];
dst = i;
minFlag = true;
}
}
i++;
}
if (minFlag)
{
visited[dst] = 1;
stack.push(dst);
System.out.print(dst + "\n");
minFlag = false;
continue;
}
stack.pop();
}
}
Given the existing structure you are using, you can output the cities in the path using:
public void printCities(Stack<Integer> path, int[][] distances, List<String> names) {
int cumulativeDistance = 0;
int previous = -1;
for (int city: path) {
if (previous != -1)
cumulativeDistance += distances[previous][city];
System.out.println(names.get(city) + " " + cumulativeDistance);
previous = city;
}
}
I'd like to answer your question slightly indirectly. You are making life hard for yourself by using arrays of objects. They make the code difficult to read and are hard to access. Things would become easier if you create a City class with appropriate methods to help you with the output.
For example:
class City {
private final String name;
private final Map<City,Integer> connections = new HashMap<>();
public static addConnection(City from, City to, int distance) {
from.connections.put(to, distance);
to.connections.put(from, distance);
}
public int getDistanceTo(City other) {
if (connections.containsKey(other))
return connections.get(other);
else
throw new IllegalArgumentException("Non connection error");
}
}
I've left out constructor, getters, setters for clarity.
Now outputting your path becomes quite a bit simpler:
public void outputPath(List<City> cities) {
int cumulativeDistance = 0;
City previous = null;
for (City current: cities) {
if (previous != null)
cumulativeDistance += previous.getDistanceTo(current);
System.out.println(current.getName + " " + cumulativeDistance);
previous = current;
}
}

jList output everything on one line

I have created a program for calculating the interest on given values. But when i calculate it, the output on the jList comes out in one line, 10 times.
Can anyone help me, and tell me why this happens :)?
From my calculate class
public ArrayList<String> calculateInterest(double years, double principal, double amount)
{
ArrayList<String> results = new ArrayList<>();
for (years = 1; years <= 10; years++)
{
amount = principal * Math.pow(rate + 1, years);
String amountToString = "" + amount;
results.add(amountToString);
}
return results;
}
´
From my GUI (Under the button)
double aar = Double.parseDouble(txtAntalAar.getText());
double belob = Double.parseDouble(txtBelob.getText());
double rente = Double.parseDouble(txtRente.getText());
ArrayList output = cal.calculateInterest(aar, belob, rente);
for (int i = 0; i < output.size(); i++)
{
myListModel.add(i, output);
}
I have also tried with:
for (String s : cal.calculateInterest(aar, rente, rente))
{
myListModel.addElement(output);
}
But same issue. Here is a photo of the output - I what them to switch line between each number:
You are adding the whole list instead of the element. Use
for (int i = 0; i < output.size(); i++)
myListModel.add(i, output.get(i));
That's because you are adding the entire ArrayList and not de item.
for (String s : cal.calculateInterest(aar, rente, rente))
{
//myListModel.addElement(output); this way you add the entire array
myListModel.addElement(s); // now you add only the item
}

submap a period of time

I'm making a info graph of my emails.
It goes quite well but things are more confusing then they have to be, for example if i want to get the amount of emails someone sended me in a month then i use this:
for (Person p : AL_persons) {
for (int y = firstYear; y <= lastYear; y++) {
for (int m = 1; m <= 12; m++) {
ArrayList<Email> emailThatMonth = new ArrayList<Email>();
for (Email e : p.emails) {
if (e.date.year().get() == y
&& e.date.monthOfYear().get() == m) {
emailThatMonth.add(e);
}
}
if (emailThatMonth.size() > maxEmailsMonth)
maxEmailsMonth = emailThatMonth.size();
}
}
}
I want to improve that so i can get it far more easy,
I was thinking of storing the first day of every month, so i can re use that.
(not tested code from here on)
ArrayList<DateTime> monthStarts = new ArrayList<DateTime>();
for (int y = firstYear; y <= lastYear; y++) {
for (int m = 1; m <= 12; m++) {
monthStarts.add(new LocalDate(y+"-"+m+"-01"));
}
}
Then to get the emails i could use a submap:
for(DateTime ld : monthStarts) {
ArrayList<Email> emailThatMonth = emails.submap(ld, ld.plusMonths(1));
}
I think this should work, however it's quite some work (not that i mind that), i just wanted to know what you guys think of it, to see if someone has tips or other ideas to deal with it.
note, i use joda time (and i love it)
The current first part looks through all the emails for each person 12*numyears times. You can simplify to only go through them once by finding the month on each email and incrementing different counters as you go. I have not tested this code since I am unsure about some specifics in your class structure.
HashMap<Person,HashMap<String,Integer>> hm = new HashMap<Person,HashMap<String,Integer>>();
for (Person p : all_persons)
{
HashMap<String,Integer> tempMap = new HashMap<String,Integer>();
for (Email e : p.emails)
{
String tag = e.date.year().get() + "-" + e.date.monthOfYear().get();
int lastvalue = tempMap.get(tag);
tempMap.put(tag, lastvalue+1);
}
hm.put(p,tempMap);
}
So for the second part(search for all emails from a given month), we take much the same approach. Iterate through once and add all matches to your new list.
String targetMonth = "2012-01";//or whatever month you're looking for
ArrayList<Email> emailThatMonth = new ArrayList<Email>();
for (Email e: emails)
{
String tag = e.date.year().get() + "-" + e.date.monthOfYear().get();
if (tag.compareToIgnoreCase(targetMonth) == 0)
emailThatMonth.add(e);
}

getting duplicate array output - java

Can someone could be kind and help me out here. Thanks in advance...
My code below outputs the string as duplicates. I don't want to use Sets or ArrayList. I am using java.util.Random. I am trying to write a code that checks if string has already been randomly outputted and if it does, then it won't display. Where I am going wrong and how do I fix this.
public class Worldcountries
{
private static Random nums = new Random();
private static String[] countries =
{
"America", "Candada", "Chile", "Argentina"
};
public static int Dice()
{
return (generator.nums.nextInt(6) + 1);
}
public String randomCounties()
{
String aTemp = " ";
int numOfTimes = Dice();
int dup = 0;
for(int i=0 ; i<numOfTimes; i++)
{
// I think it's in the if statement where I am going wrong.
if (!countries[i].equals(countries[i]))
{
i = i + 1;
}
else
{
dup--;
}
// and maybe here
aTemp = aTemp + countries[nums.nextInt(countries.length)];
aTemp = aTemp + ",";
}
return aTemp;
}
}
So the output I am getting (randomly) is, "America, America, Chile" when it should be "America, Chile".
When do you expect this to be false?
countries[i].equals(countries[i])
Edit:
Here's a skeleton solution. I'll leave filling in the helper methods to you.
public String[] countries;
public boolean contains(String[] arr, String value) {
//return true if value is already in arr, false otherwise
}
public String chooseRandomCountry() {
//chooses a random country from countries
}
//...
int diceRoll = rollDice();
String[] selection = new String[diceRoll];
for ( int i = 0; i < selection.length; i++ ) {
while (true) {
String randomCountry = chooseRandomCountry();
if ( !contains(selection, randomCountry ) {
selection[i] = randomCountry;
break;
}
}
}
//...then build the string here
This doesn't check important things like the number of unique countries.
You need a data structure which allows you to answer the question "does it already contain item X?"
Try the collection API, for example. In your case, a good candidate is either HashSet() or LinkedHashSet() (the latter preserves the insert order).
You'd probably be better of using another structure where you save the strings you have printed. Since you don't want to use a set you could use an array instead. Something like
/*
...
*/
bool[] printed = new bool[countries.length];
for(int i=0 ; i<numOfTimes ; /*noop*/ )
{
int r = nums.nextInt(countries.length);
if (printed[r] == false)
{
i = i + 1;
printed[r] = true;
aTemp = aTemp + countries[r];
aTemp = aTemp + ",";
}
}
return aTemp;
Consider what you're comparing it to:
if (!countries[i].equals(countries[i]))
are you comparing c[i] to c[i]? or c[i] to c[i-1]? Or do you need to check the whole array for a particular string? Perhaps you need a list of countries that get output.
make list uniqueCountries
for each string called country in countries
if country is not in uniqueCountries
add country to uniqueCountries
print each country in uniqueCountries
When you do this, watch out for index out of bounds, and adjust accordingly
Much faster way to do it then using HashSets and other creepy stuff. Takes less code too:
public String randomCounties() {
List<String> results = Arrays.asList(countries);
Collections.shuffle(results);
int numOfTimes = Dice();
String result = " ";
for(int i=0 ; i<numOfTimes; i++) {
result = result + countries[i] + ", ";
}
return result;
}
If you want to avoid outputting duplicate values, you need to record what values have already been listed or remove values from the pool of possibilities when they get selected.
You mention that you do not want to use Sets or ArrayList (I assume you mean Lists in general), I assume that is a requirement of the assignment. If so, you can accomplish this by building arrays and copying data between them the same way that an ArrayList would.
one note, your current implementation chooses between 1 and 6 entries from and array of 4 entries. If you force the selections to be unique you need to decide how to handle the case when you have no more unique selections.

Categories

Resources