Categories
discuss

How can I remove duplicated code between classes?

I have 2 class: RecursiveFibonacci and MemorizedRecursiveFibonacci. This is what I have so far.

RecursiveFibonacci Class

public class SimpleRecursiveFibonacci {

  public BigInteger fibonacci(int n) {
    if(n < 2) {
      return BigInteger.ONE;             
    }

    return fibonacci(n - 2).add(fibonacci(n - 1));
  }
}

and MemorizedRecursiveFibonacci Class

public class MemoizedRecursiveFibonacci {
  private Map<Integer, BigInteger> cache = new HashMap<>();

  public BigInteger fibonacci(int n) {
    if(n < 2) {
      return BigInteger.ONE;
    }
    if(!cache.containsKey(n)){
      BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));
      cache.put(n, currentFibonacci);
    }

    return cache.get(n);
  }
}

As I see, there are some duplicated code in MemorizedRecursiveFibonacci Class

 if(n < 2) {
      return BigInteger.ONE;

and

  BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));

How can I keep it DRY? remove duplicated code?

Answer

How about something like this:

public class SimpleRecursiveFibonacci {

    /** Gets the fibonacci value for n */
    public final BigInteger fibonacci(int n) {
        if (n == 0) {
            return BigInteger.ZERO;
        } else if (n == 1) {
            return BigInteger.ONE;
        }
        return getFibonacci(n);
    }

    /** Recursively calculates the fibonacci by adding the two previous fibonacci. */
    protected final BigInteger calculateFibbonacci(int n) {
        return fibonacci(n - 2).add(fibonacci(n - 1));
    }

    /** 
     * Somehow get the fibonacci value for n.
     * Could be by calculation, getting it from a cache, or anything.
     * Defaults to calculation.
     */
    protected BigInteger getFibonacci(int n) {
        return calculateFibbonacci(n);
    }

}

public class MemoizedRecursiveFibonacci extends SimpleRecursiveFibonacci {

    // Cache using an array list as recommended by user @DodgyCodeException
    private ArrayList<BigInteger> cache = new ArrayList<>();

    @Override
    protected BigInteger getFibonacci(int n) {
        if (cache.size() < n) {
            BigInteger fib = calculateFibbonacci(n);
            cache.add(fib);
            return fib;
        } else {
            return cache.get(n - 1);
        }
    }
}
Categories
discuss

Can not add submodule to android project

I am trying to import my submodule to my project but it always gives that error.

Unable to resolve dependency for ':app@debug/compileClasspath': Could not resolve project :sanservicelibrary.
Open File
Show Details


Unable to resolve dependency for ':app@debugAndroidTest/compileClasspath': Could not resolve project :sanservicelibrary.
Open File
Show Details


Unable to resolve dependency for ':app@debugUnitTest/compileClasspath': Could not resolve project :sanservicelibrary.
Open File
Show Details


Unable to resolve dependency for ':app@release/compileClasspath': Could not resolve project :sanservicelibrary.
Open File
Show Details


Unable to resolve dependency for ':app@releaseUnitTest/compileClasspath': Could not resolve project :sanservicelibrary.
Open File
Show Details

Those are didn’t help

Cant compile project with modules

Unable to resolve dependency for ‘:app@debugUnitTest/compileClasspath’, :app@debugAndroidTest/compileClasspath

App gradle.

apply plugin: 'com.android.application'

android {
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    compileSdkVersion 27
    defaultConfig {
        applicationId ".."
        minSdkVersion 18
        targetSdkVersion 27
        versionCode 13
        versionName "Beta 1.11"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary = true
        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "com.android.support:design:$supportLibVer"
    implementation "com.android.support:appcompat-v7:$supportLibVer"
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

...

    implementation project(path:':libname', configuration: 'default')

}


}

library gradle

apply plugin: 'com.android.library'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "..."
        minSdkVersion 18
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

and I have

include ':app', ':libname'

in settings gradle

Answer

You have a few of options.

OPTION 1)

Import the module through the file menu and let Android make a copy of it into your root and updates the Gradle and IDEA files etc..

OPTION 2)

You can import it via relative path. Not always recommended, but does the trick. Of course you have to be cognitive that your relative path may not match your fellow developers, so folder structure matching of repos is important if you decide to go this route.

settings.gradle should include

include 'app', ':Module 2'
project(':Module 2').projectDir = new File('../../YourPath/Project B/Module 2')

Then in your build.gradle for the app you should include

implementation project(':Module 2')

Fair Warning, some developers hate when you do it this way, but I for one see the value during the development cycle of staying with latest of a repo that may still be changing as you find issues. So there is a case for it on young modules.

OPTION 3)

Use Gradle to import compiled binaries from a Maven, jitpack, or Ivy repo. This assumes your modules are mature and ready to be packaged and used.

Categories
discuss

How can I make an RxJS Observable emit at specific datetimes?

I have an RxJS Observable that needs to be recalculated at specific times, as described by an array of DateTime objects (although for the purpose of this question they could be JavaScript Date objects, epoch milliseconds or anything else representing a specific instant in time):

const changeTimes = [
    //            yyyy, mm, dd, hh, mm
    DateTime.utc( 2018, 10, 31, 21, 45 ),
    DateTime.utc( 2018, 10, 31, 21, 50 ),
    DateTime.utc( 2018, 10, 31, 22, 00 ),
    DateTime.utc( 2018, 10, 31, 23, 00 ),
    DateTime.utc( 2018, 10, 31, 23, 30 ),
];

I’m struggling to understand how to create an Observable that would emit at the times specified in such an array.

Here’s what I’ve thought about in an attempt to answer my own question:

  • I almost certainly need to use the delay operator where the specified delay is the time between “now” and the next future datetime.
  • I somehow need to ensure that “now” is current at the time of subscription, not at the time of Observable creation—possibly by using the defer operator—although I don’t want to unnecessarily create multiple Observable instances if there are multiple subscriptions.
  • I’m unsure how to iterate over the array as time passes—the expand operator might be what I need, but it calls something recursively, and I’m just trying to iterate over a list.
  • The timer operator seems irrelevant, since the duration between each datetime is different.
  • I could map every datetime to its own delayed Observable and return them all via merge, but this becomes horribly inefficient as the number of datetimes in the array increases (there could be hundreds), so this is an absolute last resort.

How can I make an RxJS Observable that takes a list of datetimes and then emits as each one is reached in time, completing on the final one?

Answer

Given an array of DateTime objects:

const changeTimes = [
    //            yyyy, mm, dd, hh, mm
    DateTime.utc( 2018, 10, 31, 21, 45 ),
    DateTime.utc( 2018, 10, 31, 21, 50 ),
    DateTime.utc( 2018, 10, 31, 22, 00 ),
    DateTime.utc( 2018, 10, 31, 23, 00 ),
    DateTime.utc( 2018, 10, 31, 23, 30 ),
];

or better yet, an Observable that emits an array of these each time the array changes (which is what is actually happening in my scenario, although I didn’t mention it in the question because it wasn’t strictly relevant):

const changeTimes$: Observable<DateTime[]> = /* ... */;

the following Observable will immediately emit the next future time on subscription, emit each subsequent future time at the passage of the previous future time, then complete with null:

const nextTime$ = changeTimes$.pipe(
    // sort DateTimes chronologically
    map(unsorted => [...unsorted].sort((x, y) => +x - +y),
    // remove duplicates
    map(duplicated => duplicated.filter((item, i) => !i || +item !== +duplicated[i - 1])),
    // convert each time to a delayed Observable
    map(times => [...times, null].map((time, i) => defer(() => of(time).pipe(
        // emit the first one immediately
        // emit all others at the previously emitted time
        delay(i === 0 ? 0 : +times[i - 1] - +DateTime.utc())
    )))),
    // combine into a single Observable
    switchMap(observables => concat(...observables)),
);
  • Sorting is necessary since each inner Observable (“wait X milliseconds then report a time”) is subscribed to on completion of the previous.
  • Removing duplicates is not strictly necessary, but seems appropriate to cater for.
  • defer is used so that the current time is calculated when the inner Observable is subscribed to.
  • concat is used to execute each inner Observable in succession (thanks to martin), avoiding the overhead of a subscription for each time in the list simultaneously.

The way this satisfies my original need:

I have an RxJS Observable that needs to be recalculated at specific times, as described by an array of DateTime objects…

is if I combine this with the data requiring recalculation using the combineLatest operator to trigger that recalculation at the correct times:

const timeAwareData$ = combineLatest(timeUnawareData$, nextTime$).pipe(
    tap(() => console.log('either the data has changed or a time has been reached')),
    // ...
);

What I don’t like about my solution

It creates a separate inner Observable, concurrently, for every time in the list. I feel like it’s possible to refactor such that each inner Observable is only created after the previous one is destroyed. Any improvement tips would be gratefully received.

Categories
discuss

Use custom component in overlay attribute in AntD

I am trying to add a custom right-click menu component to a menu item. I can do it via a const but when I do it with a component, styles seems to work wrong. Any idea?

Working example: https://codesandbox.io/s/m5n31opx2j

My custom menu:

import React from "react";
import ReactDOM from "react-dom";
import Dropdown from "antd/lib/dropdown";
import Menu from "antd/lib/menu";
import "antd/dist/antd.css";

export default class MyMenu extends React.Component {
  render() {
    return (
      <Menu>
        <Menu.Item
          onClick={e => {
            alert("clicked");
          }}
        >
          click
        </Menu.Item>
        <Menu.Item>Like it</Menu.Item>
        <Menu.Item>Bookmark</Menu.Item>
      </Menu>
    );
  }
}

My main component:

import React from "react";
import ReactDOM from "react-dom";
import Dropdown from "antd/lib/dropdown";
import Menu from "antd/lib/menu";
import "antd/dist/antd.css";
import MyMenu from "./MyMenu";

const menu = (
  <Menu>
    <Menu.Item
      onClick={e => {
        alert("clicked");
      }}
    >
      click
    </Menu.Item>
    <Menu.Item>Like it</Menu.Item>
    <Menu.Item>Bookmark</Menu.Item>
  </Menu>
);

class App extends React.Component {
  render() {
    return (
      <div>
        <Menu mode="horizontal">
          <Menu.Item
            key="1"
            onClick={() => {
              alert("parent clicked");
            }}
          >
            <Dropdown overlay={menu} trigger={[`contextMenu`]}>
              <span style={{ userSelect: "none" }}> from const </span>
            </Dropdown>
          </Menu.Item>

          <Menu.Item
            key="2"
            onClick={() => {
              alert("parent clicked");
            }}
          >
            <Dropdown overlay={<MyMenu />} trigger={[`contextMenu`]}>
              <span style={{ userSelect: "none" }}> from component </span>
            </Dropdown>
          </Menu.Item>
        </Menu>
      </div>
    );
  }
}

const APP_NODE = document.getElementById(`container`);
ReactDOM.render(<App />, APP_NODE);

Answer

This is because in component you are wrapping Menu with react class. And you loose inheritance of antd Dropdown component.

So you need to pass Menu directly to overlay property of Dropdown component as you did it with constant menu:

That is just how component works.

To stay with custom component approach, you need to include Dropdown in MyMenu component so that Menu is passed directly to overlay prop:

import React from "react";
import ReactDOM from "react-dom";
import Dropdown from "antd/lib/dropdown";
import Menu from "antd/lib/menu";
import "antd/dist/antd.css";

const menu = (
  <Menu>
    <Menu.Item
      onClick={e => {
        alert("clicked");
      }}
    >
      click
  </Menu.Item>
    <Menu.Item>Like it</Menu.Item>
    <Menu.Item>Bookmark</Menu.Item>
  </Menu>
);

export default class MyMenu extends React.Component {
  render() {
    return (
      <Dropdown overlay={menu} trigger={[`contextMenu`]}>
        <span style={{ userSelect: "none" }}> from const </span>
      </Dropdown>
    );
  }
}

Hope this helps.

Here you can see directly in the source code how that is done: https://github.com/ant-design/ant-design/blob/557683c7644d2aef1e2df0490815b294b063d457/components/dropdown/dropdown.tsx#L74

Categories
discuss

Android two way data binding with room table models

So I have room model classes annotated with @Entity annotation which contain fields annotated with @ColumnInfo.

I also have a view that binds to the object of this model:

   <EditText
        android:id="@+id/sadfadsdfasd"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:gravity="center"
        android:hint="@string/assdsa"
        android:inputType="text"
        android:text="@={fuelPrice.modification}" />

Like this it works when displaying EditText. It shows value from my model, but when I modify EditText, that modification is not being stored in my object even though I use @= signs which indicate two way binding.

So if I understand correctly, I can’t really use POJO with simple primitive fields for two way data binding and instead I should have all fields as observables of required type or fields wrapped in LiveData?

If above case is true, does that mean that to have two way binding for room entities, I have to create separate class for each entity which would implement all the observable fields and update my entity object accordingly? Or is there a simplier solution?

EDIT Above case was false. Seems like two way binding does work for simple POJO classes with appropriate getters and setters.

Answer

AFAIK I just tested it, it should work without ObservableField given that modification is a private field with standard getters and setters. Using

android:text="@={fueldPrice.modification}"

and

class FuelPrice {
    private String modification;

    public String getModification() {
        return modification;
    }

    public String setModification(String modification) {
        this.modification = modification;
    }
}

It also works if you just use a public field

class FuelPrice {
    public String modification;
}
Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..