This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Singleton private constructor(application: Application) { | |
companion object { | |
@Volatile | |
private var INSTANCE: Singleton? = null | |
fun getInstance(application: Application): Singleton = | |
INSTANCE ?: synchronized(this) { | |
INSTANCE | |
?: Singleton(application).also { INSTANCE = it } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// https://stackoverflow.com/a/52075248/6641096 | |
fun <T> MutableLiveData<T>.notifyObserver() { | |
this.value = this.value | |
} | |
// Usage | |
fun addSomething(item: Item) { | |
listLiveData.value?.add(item) | |
listLiveData.notifyObserver() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def batch(iterable, size, drop_remainder=False): | |
if size < 1: | |
raise ValueError("size must be greater than zero.") | |
iterator = iter(iterable) | |
while True: | |
try: | |
items = [] | |
for _ in range(size): | |
items.append(next(iterator)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class LiveChange<T>(val source: LiveData<T>, ignoreFirst: Boolean = false) : MediatorLiveData<T>() { | |
private var shouldIgnoreNext: Boolean = ignoreFirst | |
init { | |
addSource(source) { | |
if (shouldIgnoreNext) { | |
shouldIgnoreNext = false | |
} else { | |
if (value != it) value = it | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import functools | |
def renewing(generator): | |
""" | |
A decorator to turn a generator into an object that can be | |
iterated multiple times, restarting the generator each time. | |
""" | |
class RenewingGenerator: | |
def __init__(self, *args, **kwargs): | |
self.args = args |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
_numeric_types = (int, float, complex) | |
class NumericDict(dict): | |
def __add__(self, other): | |
if isinstance(other, _numeric_types): | |
return self.apply(lambda v: v + other) | |
if isinstance(other, NumericDict): | |
return self.__class__({k: v + other.get(k, 0) for k, v in self.items()}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# items must be sorted from best to worst | |
def non_max_suppress(items_sorted, suppress_predicate): | |
num_items = len(items_sorted) | |
skip = [False]*num_items | |
i = 0 | |
while i < num_items: | |
if skip[i]: | |
i += 1 | |
continue |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// It joins words grammatically e.g. ["apple", "orange", "banana"] -> "apple, orange and banana" | |
/// and parameter is required to support different languages | |
func joinGrammatically(words: [String], and: String) -> String { | |
if words.count == 0 { | |
return "" | |
} | |
else if words.count == 1 { | |
return words.first! | |
} | |
else { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
func callBlocking<T>( | |
_ closure: @escaping (_ continuationHandler: @escaping (T) -> Void ) -> Void ) | |
-> T { | |
let dispatchGroup = DispatchGroup() | |
dispatchGroup.enter() | |
var result:T? = nil | |
closure { res in | |
result = res | |
dispatchGroup.leave() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// implemented according to this answer | |
// https://stackoverflow.com/a/24755958/6641096 | |
func measureInMilliseconds(_ block: () -> ()) -> UInt64 { | |
let start = DispatchTime.now() | |
block() | |
let end = DispatchTime.now() | |
// Difference in nano seconds (UInt64) | |
let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds |
OlderNewer