Onomatopoeia is a word that sounds like what it means. They help you hear what is going on. For example, “thud”, “crash”, “bang” and “buzz” are all examples of onomatopoeia. Animal sounds are often onomatopoeic: “roar”, “meow”, “moo”, “cluck”, “oink”1.
Here are some more examples of onomatopoeia:
Buzz: the sound of a bee
Sizzle: the sound of frying food
Hiss: the sound of a snake
Splash: the sound of water hitting something
Crackle: the sound of fire burning
I hope this helps you get started with your blog post! Let me know if you have any other questions.
Author: John Rowan
Creational Design Patterns in Kotlin Android
Creational design patterns are a set of solutions to common software development problems that deal with how objects are being created. Using such patterns will ensure that your code is flexible and reusable, and that you avoid hard-coded dependencies and tight coupling between classes.
In this blog post, I will show you some of the most important and widely used creational design patterns in Kotlin Android. You will learn how to apply these patterns to your projects and how they can help you write better and more maintainable code. I will cover four creational design patterns:
- Factory and abstract factory (provider model) method
- Singleton
- Builder
- Dependency injection
Factory and abstract factory (provider model) method
The factory method pattern defines an interface for creating an object, but lets subclasses decide which class to instantiate. The abstract factory pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes.
These patterns are useful when you want to decouple the creation of objects from their usage, or when you want to provide different implementations of the same interface depending on some conditions. For example, you can use these patterns to create different types of views or fragments based on the device configuration or user preferences.
In Kotlin, you can use the provider model to implement these patterns. The provider model is a way of creating objects using lambda expressions or function references that act as factories. For example, you can use a provider function to create different types of fragments based on a parameter:
// An interface for fragments that display some content interface ContentFragment { fun showContent(content: String) } // A concrete implementation of ContentFragment that shows content in a text view class TextFragment : Fragment(), ContentFragment { private lateinit var textView: TextView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.text_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) textView = view.findViewById(R.id.text_view) } override fun showContent(content: String) { textView.text = content } } // Another concrete implementation of ContentFragment that shows content in a web view class WebFragment : Fragment(), ContentFragment { private lateinit var webView: WebView override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { return inflater.inflate(R.layout.web_fragment, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) webView = view.findViewById(R.id.web_view) } override fun showContent(content: String) { webView.loadUrl(content) } } // A provider function that returns a ContentFragment based on a parameter fun provideContentFragment(type: String): ContentFragment = when (type) { "text" -> TextFragment() "web" -> WebFragment() else -> throw IllegalArgumentException("Unknown type: $type") }
Singleton
The singleton pattern ensures that a class has only one instance and provides a global point of access to it. This pattern is useful when you want to have a single source of truth for some data or functionality in your app. For example, you can use this pattern to create a repository that handles data access from different sources.
In Kotlin, you can use the object declaration to create a singleton class. The object declaration combines a class declaration and a single instance of that class into one expression. For example, you can use an object declaration to create a news repository that fetches data from a remote data source:
// A singleton class that acts as a repository for news data object NewsRepository { // A reference to the remote data source private val newsRemoteDataSource = // getDataSource() // A flow that emits the latest news from the remote data source val latestNews: Flow<List<ArticleHeadline>> = newsRemoteDataSource.latestNews // A function that returns the details of an article by its id suspend fun getArticleDetails(id: String): ArticleDetails { return newsRemoteDataSource.getArticleDetails(id) } }
Builder
The builder pattern separates the construction of a complex object from its representation so that the same construction process can create different representations. This pattern is useful when you want to create objects with many optional parameters or when you want to have more control over how the object is constructed. For example, you can use this pattern to create an alert dialog with various options.
In Kotlin, you can use named arguments and default values to implement this pattern. Named arguments allow you to specify the name of a parameter when calling a function, which makes the code more readable and avoids errors when there are many parameters. Default values allow you to omit some parameters when calling a function if they have a predefined value. For example, you can use named arguments and default values to create an alert dialog builder class:
// A class that represents an alert dialog with various options class AlertDialog( val title: String, val message: String, val positiveButton: String = "OK", val negativeButton: String? = null, val icon: Int? = null, val onPositiveClick: () -> Unit = {}, val onNegativeClick: () -> Unit = {} ) { // A function that shows the alert dialog on the screen fun show() { // Create and display an alert dialog using the Android SDK ... } } // A builder class that creates an AlertDialog instance using named arguments and default values class AlertDialogBuilder { // A function that returns an AlertDialog instance with the given parameters fun build( title: String, message: String, positiveButton: String = "OK", negativeButton: String? = null, icon: Int? = null, onPositiveClick: () -> Unit = {}, onNegativeClick: () -> Unit = {} ): AlertDialog { return AlertDialog( title = title, message = message, positiveButton = positiveButton, negativeButton = negativeButton, icon = icon, onPositiveClick = onPositiveClick, onNegativeClick = onNegativeClick ) } }
Dependency injection
The dependency injection pattern is a technique whereby one object supplies the dependencies of another object. A dependency is an object that can be used (a service). An injection is the passing of a dependency to a dependent object (a client) that would use it.
This pattern is useful when you want to reduce coupling and increase testability between classes by delegating the responsibility of creating and providing dependencies to another object or framework. For example, you can use this pattern to inject dependencies into your activities or view models.
In Kotlin Android, you can use frameworks like Dagger or Koin to implement this pattern. These frameworks provide annotations or DSLs to define dependencies and inject them into your classes. For example, you can use Koin to inject dependencies into your view model:
// A class that represents a user profile view model with some dependencies class UserProfileViewModel( private val userRepository: UserRepository, private val analyticsService: AnalyticsService ) : ViewModel() { // Some view model logic using userRepository and analyticsService ... } // A module that defines dependencies using Koin DSL val appModule = module { // Define UserRepository as a singleton using factory function single<UserRepository> { UserRepositoryImpl(get()) } // Define AnalyticsService as a singleton using constructor injection single<AnalyticsService> { AnalyticsServiceImpl() } // Define UserProfileViewModel using constructor injection viewModel { UserProfileViewModel(get(), get()) } } // Start Koin with appModule in Application class class MyApp : Application() { override fun onCreate() { super.onCreate() startKoin { androidContext(this@MyApp) modules(appModule) } } } // Get UserProfileViewModel instance using Koin extension function in Activity class class UserProfileActivity : AppCompatActivity() { // Inject UserProfileViewModel private val viewModel by viewModel<UserProfileViewModel>() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_user_profile) // Use viewModel ... } }
Conclusion
In this blog post, you learned how to use creational design patterns in Kotlin Android. You learned how to apply these patterns to your projects and how they can help you write better and more maintainable code. You learned how to use factory and abstract factory (provider model) method, singleton, builder, and dependency injection patterns.
If you want to learn more about design patterns and other Kotlin features for Android development, check out these resources:
- Design Patterns for Dummies
- Mastering Design Patterns in Android with Kotlin
- Kotlin flows on Android
- Dependency injection with Koin
I hope you enjoyed this blog post and found it useful. Happy coding! 😊
TP-Link AX1800 WiFi 6 Router V4 (Archer AX21) – Dual Band Wireless Internet, Gigabit, Easy Mesh, Works with Alexa - A Certified for Humans Device, Free Expert Support
$54.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Amazon Fire HD 10 Kids Pro tablet (newest model) ages 6-12. Bright 10.1" HD screen, includes ad-free content, robust parental controls, 13-hr battery and slim case for older kids, 32 GB, Happy Day
$189.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Amazon Fire HD 10 tablet (newest model) built for relaxation, 10.1" vibrant Full HD screen, octa-core processor, 3 GB RAM, 64 GB, Lilac
$101.10 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)TP-Link AXE5400 Tri-Band WiFi 6E Router (Archer AXE75)- Gigabit Wireless Internet Router, ax Router for Gaming, VPN Router, OneMesh, WPA3, Black
$149.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Amazon eero 6 mesh wifi extender - Add up to 1,500 sq. ft. of Wi-Fi 6 coverage to your existing eero mesh wifi network
$79.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)How to use Flow in Android Programming
Flow is a stream processing API in Kotlin developed by JetBrains1. It’s an implementation of the Reactive Stream specification, an initiative whose goal is to provide a standard for asynchronous stream processing1. Jetbrains built Kotlin Flow on top of Kotlin Coroutines, which means that you can use suspend functions to produce and consume values asynchronously2.
In this blog post, I will show you how to use Flow in your Android project to handle live data updates and endless streams of data. You will learn how to create flows, modify them, collect them, and use StateFlow and SharedFlow to share state and events across your app.
Creating a flow
To create flows, use the flow builder APIs. The flow builder function creates a new flow where you can manually emit new values into the stream of data using the emit function2. For example, you can use a flow to receive live updates from a network API:
class NewsRemoteDataSource( private val newsApi: NewsApi, private val refreshIntervalMs: Long = 5000 ) { val latestNews: Flow<List<ArticleHeadline>> = flow { while(true) { val latestNews = newsApi.fetchLatestNews() emit(latestNews) // Emits the result of the request to the flow delay(refreshIntervalMs) // Suspends the coroutine for some time } } } // Interface that provides a way to make network requests with suspend functions interface NewsApi { suspend fun fetchLatestNews(): List<ArticleHeadline> }
The flow builder is executed within a coroutine. Thus, it benefits from the same asynchronous APIs, but some restrictions apply:
- Flows are sequential. As the producer is in a coroutine, when calling a suspend function, the producer suspends until the suspend function returns2.
- Flows are cold. This means that the flow builder is called every time a terminal operator is applied to the flow2. Terminal operators are functions that start collecting values from the flow, such as collect or first.
Modifying the stream
You can use various operators to transform or filter the values emitted by a flow. For example, you can use map to apply a function to each value, filter to remove unwanted values, or combine to merge two flows into one2. For example, you can use map to convert the list of article headlines into a list of article titles:
val latestNewsTitles: Flow<List<String>> = latestNews.map { headlines -> headlines.map { headline -> headline.title } }
You can also use operators that are specific to flows, such as debounce or distinctUntilChanged. These operators help you deal with flows that emit values too frequently or unnecessarily2. For example, you can use debounce to ignore values that are emitted in quick succession:
val debouncedNewsTitles: Flow<List<String>> = latestNewsTitles.debounce(1000) // Ignores values that are emitted less than 1000 ms apart
Collecting from a flow
To start receiving values from a flow, you need to collect it. Collecting is a terminal operation that triggers the execution of the flow and invokes a given action for every value emitted by the flow2. You need to collect flows from a coroutine or a suspend function. For example, you can collect the debounced news titles from an activity:
class LatestNewsActivity : AppCompatActivity() { private val newsRemoteDataSource = // getDataSource() override fun onCreate(savedInstanceState: Bundle?) { ... // Start a coroutine in the lifecycle scope lifecycleScope.launch { // repeatOnLifecycle launches the block in a new coroutine every time the // lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED. repeatOnLifecycle(Lifecycle.State.STARTED) { // Trigger the flow and start listening for values. newsRemoteDataSource.debouncedNewsTitles.collect { titles -> // Update UI with new titles } } } } }
Note that collecting from a flow can be a suspending operation if the flow is infinite or slow. This means that you should not collect from multiple flows sequentially in the same coroutine, as this will block the execution of the next collect until the previous one finishes. Instead, you should launch multiple coroutines or use other operators like zip or flatMapMerge to collect from multiple flows concurrently2.
StateFlow and SharedFlow
StateFlow and SharedFlow are Flow APIs that enable flows to optimally emit state updates and emit values to multiple consumers3.
StateFlow is a state-holder observable flow that emits the current and new state updates to its collectors. The current state value can also be read through its value property. To update state and send it to the flow, assign a new value to the value property of the MutableStateFlow class3.
In Android, StateFlow is a great fit for classes that need to maintain an observable mutable state. For example, you can use StateFlow to expose UI state from a ViewModel:
class LatestNewsViewModel( private val newsRepository: NewsRepository ) : ViewModel() { // Backing property to avoid state updates from other classes private val _uiState = MutableStateFlow(LatestNewsUiState.Success(emptyList())) // The UI collects from this StateFlow to get its state updates val uiState: StateFlow<LatestNewsUiState> = _uiState init { viewModelScope.launch { newsRepository.favoriteLatestNews // Update View with the latest favorite news // Writes to the value property of MutableStateFlow, // adding a new element to the flow and updating all // of its collectors .collect { favoriteNews -> _uiState.value = LatestNewsUiState.Success(favoriteNews) } } } } // Represents different states for the LatestNews screen sealed class LatestNewsUiState { data class Success(val news: List<ArticleHeadline>): LatestNewsUiState() data class Error(val exception: Throwable): LatestNewsUiState() }
Unlike a cold flow built using the flow builder, a StateFlow is hot: collecting from the flow doesn’t trigger any producer code. A StateFlow is always active and in memory, and it becomes eligible for garbage collection only when there are no other references to it from a garbage collection root. When a new consumer starts collecting from the flow, it receives the last state in the stream and any subsequent states. You can find this behavior in other observable classes like LiveData3.
SharedFlow is an observable hot flow that emits values only when active collectors are present. Unlike StateFlow, SharedFlow does not have any initial value nor does it store any value at all. To emit values into SharedFlow use its emit function3.
In Android, SharedFlow is useful for sharing events among multiple consumers without having any initial value or state associated with them. For example, you can use SharedFlow to broadcast user input events across your app:
class UserInputManager { // Creates an instance of MutableSharedFlow with zero replay buffer size, // meaning that only new events will be emitted by this SharedFlow. private val _userInputEvents = MutableSharedFlow<UserInputEvent>() // Exposes only SharedFlow interface so other classes cannot modify it. val userInputEvents: SharedFlow<UserInputEvent> = _userInputEvents fun onUserInput(event: UserInputEvent) { viewModelScope.launch { _userInputEvents.emit(event) // Emits event into SharedFlow } } } // Represents different types of user input events sealed class UserInputEvent { data class Tap(val x: Float, val y: Float): UserInputEvent() data class Swipe(val direction: Direction): UserInputEvent() }
To collect from StateFlow or SharedFlow, you can use any terminal operator like collect or first as with any other flow.
Conclusion
In this blog post, you learned how to use Flow in your Android project to handle live data updates and endless streams of data. You learned how to create flows, modify them, collect them, and use StateFlow and SharedFlow to share state and events across your app.
If you want to learn more about Flow and other Kotlin features for Android development, check out these resources:
- Kotlin flows on Android
- StateFlow and SharedFlow
- Guide to app architecture
- What is Flow in Kotlin and How to use it in Android Project?
I hope you enjoyed this blog post and found it useful. Happy coding! 😊
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display, 1 x Powered USB-C 5Gbps & 2×Powered USB-A 3.0 5Gbps Data Ports for MacBook Pro, MacBook Air, Dell and More
$19.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Amazon Fire Max 11 tablet (newest model) vivid 11” display, all-in-one for streaming, reading, and gaming, 14-hour battery life, optional stylus and keyboard, 64 GB, Gray
$229.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)TP-Link AXE5400 Tri-Band WiFi 6E Router (Archer AXE75)- Gigabit Wireless Internet Router, ax Router for Gaming, VPN Router, OneMesh, WPA3, Black
$149.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Anker Laptop Charger, 140W MAX USB C Charger, 4-Port Multi-Device Fast Charging, Advanced GaN Power Adapter, Intuitive Touch Controls, for MacBook, iPhone 16 Series, Samsung Galaxy, Pixel, and More
$99.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Amazon Fire HD 10 tablet (newest model) built for relaxation, 10.1" vibrant Full HD screen, octa-core processor, 3 GB RAM, 64 GB, Ocean
$100.46 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Investing indicators
It is important to understand the various indicators that can be used to place successful trades. These indicators are based on a variety of factors that can be used to determine the overall market outlook, including technical and fundamental analysis. In this blog, we will discuss the best indicators to use when placing successful trades, and delve into the details of each indicator.
1. Moving Averages: A moving average is a commonly used indicator in trading that helps to smooth out price movements and reveal the overall trend. Simple moving averages (SMA) and exponential moving averages (EMA) are the two most common types of moving averages used in trading.
2. Relative Strength Index (RSI): The Relative Strength Index (RSI) is a momentum indicator that measures the magnitude of recent price changes to evaluate overbought or oversold situations in the market. RSI is most commonly used on a 14-day timeframe.
3. MACD: The Moving Average Convergence Divergence (MACD) is a trend-following momentum indicator that shows the relationship between two moving averages of a security’s price.
4. Bollinger Bands: Bollinger Bands are a volatility indicator that creates a band above and below the price of a security. The band expands when a security is volatile and contracts when the market is quiet. Bollinger Bands help traders to identify potential breakouts, breakdowns, and trend continuations.
5. Fibonacci Retracement: The Fibonacci Retracement is a technical analysis tool that helps traders identify potential support and resistance levels based on significant price movements. Fibonacci retracements are based on the idea that securities will often retrace a predictable portion of a move, after which the trend can resume.
It is important to note that these indicators should be used in combination with other means of analysis, rather than in isolation. For example, while moving averages may indicate a trend, it is important to look at other indicators such as the RSI to determine whether a security is oversold or overbought.
In conclusion, the above-mentioned indicators are some of the best indicators to use when placing successful trades in the market. It is recommended that traders use these indicators in combination with other means of analysis and not rely solely on these indicators for decision making. In the end, successful trading requires patience and a well-rounded understanding of the market, so traders should be willing to continually educate themselves on new trading strategies and indicators.
Feral cat Trap Neuter Return program
As an avid cat lover, I believe that it is absolutely critical for us as a society to effectively manage the feral cat population. One of the most effective and humane methods to do so is through what is known as a trap-neuter-return program.
Unlike dogs, cats are not naturally social animals, and many are able to survive perfectly fine on their own. However, it is important to remember that cats are also prolific breeders, and it is estimated that a single female cat can produce up to 100 offspring over the course of her life. This leads to an overpopulation of feral cats that can cause a number of problems for both the cats themselves and for the communities in which they live.
The trap-neuter-return program (TNR) involves trapping feral cats, neutering or spaying them, and then returning them to their natural habitat. This program is designed to keep the cats from reproducing while also preventing the need to euthanize otherwise healthy animals.
Here are a few key reasons why TNR is such an effective and humane solution to the feral cat population problem:
– It prevents overpopulation: By spaying or neutering feral cats, TNR programs help prevent the population from growing out of control. This is a sustainable solution that keeps the cat population at a manageable level without requiring ongoing intervention from animal control or other groups.
– It reduces health problems: Feral cats are often riddled with health problems, from fleas and ticks to infections and diseases. By providing them with medical attention, TNR programs can help prevent the spread of illness and make it easier for cats to lead healthier, happier lives.
– It is humane: Unlike traditional animal control measures, such as euthanasia, TNR programs are non-lethal and allow cats to continue living in their natural habitats. This is a more compassionate approach that recognizes the value of cats as living beings with inherent worth.
Of course, there are some challenges associated with TNR programs. For example, capturing feral cats can be difficult and time-consuming, and there is always the risk that some cats will be missed. That said, with proper planning and execution, TNR programs have proven to be a highly effective way of managing feral cat populations.
I strongly support the use of TNR programs as a humane and effective method for managing feral cat populations. If you are interested in learning more about TNR programs in your area or how you can get involved in supporting this important cause, talk to your local animal shelter or veterinarian today. Together, we can make a real difference in the lives of cats and the communities they call home.
Temptations Classic Crunchy and Soft Cat Treats Seafood Medley Flavor, 30 oz. Tub
$13.93 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Sheba Perfect Portions Wet Cat Food Cuts in Gravy Variety Pack, Roasted Chicken Entree and Tender Turkey Entree, 2.6 oz. Twin-Pack Trays (12 Count, 24 Servings)
$10.49 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Temptations MixUps Crunchy and Soft Cat Treats Surfer's Delight Flavor, 16 oz. Tub
$8.48 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Vital Essentials Minnows Cat Treats, 0.5 oz | Freeze-Dried Raw | Single Ingredient | Grain Free, Gluten Free, Filler Free
$7.00 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Purina Friskies Natural Cat Treats, Party Mix Natural Yums With Wild Caught Tuna and Added Vitamins, Minerals and Nutrients - 20 oz. Canister
$8.48 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Kotlin Nullability with extension functions and examples
Nullability and Common Extension Functions in Kotlin Explained with Code Examples
Kotlin is a statically typed programming language that was designed to be a safer alternative to Java. One of the ways it achieves this safety is through nullability, which allows developers to prevent null pointer exceptions at runtime by making them compile-time errors. In this blog post, we will explore nullability in Kotlin and common extension functions that can help you work with null values more efficiently.
Nullability in Kotlin
Nullability is a concept in programming that refers to the ability of a variable or object to hold a null value. In Kotlin, nullability is controlled with two types: nullable and non-nullable. A nullable type can hold a null value, while a non-nullable type cannot.
To make a variable or object nullable in Kotlin, you simply add a question mark after its type. For example, the following code creates a nullable String:
var nullableString: String? = null
To make a variable or object non-nullable in Kotlin, you do not add a question mark after its type. For example, the following code creates a non-nullable String:
val nonNullableString: String = “Hello, World!”
If you try to assign a null value to a non-nullable type, the compiler will give you an error:
val nonNullableString: String = null // Error: Null can not be value of a non-null type String
Common Extension Functions for Nullability
There are several extension functions in Kotlin that can help you work with null values more efficiently. Let’s look at some of the most common ones:
1. safeCall
The safeCall function allows you to execute a method or property on a nullable object without the risk of a null pointer exception. If the object is null, the function returns null.
For example, the following code uses the safeCall function to print the length of a nullable String:
val nullableString: String? = null
println(nullableString?.length) // Prints null
2. Elvis Operator
The Elvis operator allows you to assign a default value to a nullable variable or object. If the value is null, the operator returns the default value instead.
For example, the following code uses the Elvis operator to assign a default value to a nullable String:
val nullableString: String? = null
val length = nullableString?.length ?: -1
println(length) // Prints -1
3. Let Function
The let function allows you to execute a block of code if a nullable variable or object is not null. Inside the block, the variable or object is called with the it keyword.
For example, the following code uses the let function to print the length of a nullable String if it is not null:
val nullableString: String? = “Hello, World!”
nullableString?.let { println(it.length) } // Prints 13
4. Nullable Type Conversion
The toIntOrNull and toDoubleOrNull functions allow you to convert a nullable String to an Int or Double, respectively. If the String is null or cannot be parsed, the functions return null.
For example, the following code converts a nullable String to an Int using the toIntOrNull function:
val nullableString: String? = “123”
val nullableInt: Int? = nullableString?.toIntOrNull()
println(nullableInt) // Prints 123
In conclusion, nullability is an essential concept in Kotlin that helps prevent null pointer exceptions. By using common extension functions like safeCall, Elvis operator, Let function, and nullable type conversion, you can work with null values more efficiently and safely. We hope this blog post has been helpful in understanding nullability in Kotlin and its common extension functions.
havit HV-F2056 15.6"-17" Laptop Cooler Cooling Pad - Slim Portable USB Powered (3 Fans), Black/Blue
$27.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Mac Book Pro Charger - 118W USB C Charger Fast Charger Compatible with MacBook pro/Air, M1 M2 M3 M4, ipad Pro, Samsung Galaxy and All USB C Device, Include Charge Cable
$26.83 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)UGREEN Revodok 105 USB C Hub 5 in 1 Multiport Adapter 4K HDMI, 100W Power Delivery, 3 USB-A Data Ports, USB C Dongle for MacBook Pro/Air, iPad Pro, iMac, iPhone 15 Pro/Pro Max, XPS, Thinkpad
$11.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Amazon eero 6+ mesh wifi system - Supports internet plans up to a Gigabit, Coverage up to 4,500 sq. ft., Connect 75+ devices, 3-pack
$299.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display, 1 x Powered USB-C 5Gbps & 2×Powered USB-A 3.0 5Gbps Data Ports for MacBook Pro, MacBook Air, Dell and More
$19.99 (as of July 13, 2025 20:38 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Foraging for Mushrooms
There is nothing better than heading out to the forest to find wild edible mushrooms, especially in Pennsylvania where there is a wide variety of gourmet forms. The Pennsylvania woods are a haven for those who have a desire to hunt for the elusive edible mushrooms that can only be found in the wild. As a beginner, mushroom hunting can be overwhelming as there are many different types of wild mushrooms and some look very similar to each other. Here’s a guide to help you identify and learn more about the most common wild edible mushrooms in Pennsylvania.
Chanterelles
Chanterelle mushrooms are a well-known and highly prized wild edible mushroom that grows in Pennsylvania. They are typically found near oak, poplar, and birch trees in late June to early August. Chanterelles have a delicate, slightly nutty, and earthy flavor that pairs well with poultry, seafood, and cream-based sauces. They have a distinctive trumpet shape with a golden-yellow color and a slightly ridged cap.
Morels
Morels are highly sought after by mushroom hunters due to their meaty, nutty flavor, and distinct honeycomb texture. They are found in late April to early June in Pennsylvania, usually under deciduous trees. They are cone-shaped with deep, irregular furrows, and range in color from pale grey to almost black.
Lobster Mushrooms
The Lobster Mushroom, an oddity, is not a mushroom but a parasitic fungus that grows on other mushrooms such as the Lactifluus piperatus or Russula brevipes. These mushrooms have a firm texture with a red-orange color that is similar to that of lobster meat. The flavor is mildly sweet and slightly nutty. They grow from June to September and can be found near oak, beech, and pine trees.
Cauliflower Mushrooms
Cauliflower mushrooms, also known as Sparassis crispa, are found in late August to early October in Pennsylvania. The mushroom is large, white, and resembles a head of cauliflower. They can grow up to a foot wide and have a distinct aroma with a delicate, sweet flavor that pairs well with poultry and fish.
Hen of the Woods
Hen of the Woods, also known as Maitake mushrooms, is highly valued for its earthy flavor which is similar to roasted chicken. They grow on the base of hardwood trees such as oak and maples. They have a distinct layered structure that becomes visible when they grow to maturity. They grow from August to October in Pennsylvania.
In conclusion, mushroom hunting can be a fun and rewarding activity, but it is important to only eat mushrooms that have been positively identified as safe to consume. Always consult an expert before consuming mushrooms, and never eat mushrooms that show any signs of decay or slime. With these tips in mind, a day spent foraging for mushrooms in the Pennsylvania woods can be a memorable experience. Happy hunting!
Intex 64417ED 22in Queen Dura-Beam Comfort Plush High-Rise Inflatable Air Mattress with Built in Pump for Travel and Camping, 600lb Weight Capacity
$53.19 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Aegend Swim Goggles, Swimming Goggles No Leaking Full Protection Adult Men Women Youth
$9.99 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Amazon Basics High Density Foam Roller for Exercise and Recovery
$17.57 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)CAP Barbell Coated Hex Dumbbell Weight | Multiple Options
$20.00 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)HydroJug Sport - Stainless Steel Tumbler with Straw, Vacuum Insulated, 40oz Leakproof Water Bottle, Ergonomic Design, Reusable, Dishwasher Safe, Rubber Base, Durable for Gym or Outdoors, Sage
$39.99 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Erie, Pennsylvania is a great place to catch steelhead trout
Erie, Pennsylvania is a great place to catch steelhead trout. The city is located on the shores of Lake Erie, which is a popular destination for anglers of all levels of experience. Steelhead trout are a type of migratory fish that travel from the ocean to freshwater rivers to spawn. They are known for their strong fight and beautiful coloration.
If you’re looking to catch steelhead trout in Erie, there are a few things you’ll need to know. First, the best time to fish for steelhead is during the spring and fall. Second, you’ll need to use the right gear. Steelhead trout are strong fish, so you’ll need a sturdy rod and reel. You’ll also need to use heavy-duty line and weights.
Once you have the right gear, you’ll need to find a good spot to fish. There are many public access points along the shores of Lake Erie where you can fish for steelhead trout. You can also fish from a boat, but this is not necessary.
When you’re fishing for steelhead trout, it’s important to use the right bait. Steelhead trout are attracted to bright colors, so you’ll want to use lures that are brightly colored. You can also use live bait, such as salmon eggs or nightcrawlers.
Once you’ve found a good spot and have the right gear and bait, it’s time to start fishing. Steelhead trout are usually found in the deeper water near the bottom of the river. You’ll want to cast your lure or bait out into the river and then slowly reel it in.
If you’re lucky, you’ll feel a tug on your line. This means that you’ve hooked a steelhead trout! Now it’s time to start reeling it in. Steelhead trout are strong fish, so be prepared for a fight. Once you’ve reeled the steelhead trout in, you can release it back into the river or keep it for dinner.
Here are some additional tips for catching steelhead trout in Erie:
- Fish early in the morning or late in the evening when the water is cooler.
- Use a light tippet (the line that connects your lure or bait to your main line) to help you feel the bite.
- Be patient and persistent. Steelhead trout can be difficult to catch, but it’s worth the effort when you finally land one.
Here are some of the best places to fish for steelhead trout in Erie:
- Presque Isle State Park
- Girard Dam
- Conneaut Lake
- French Creek State Park
- Elk Creek State Park
- Shenango River
There are many different ways to cook steelhead trout. Here are a few popular methods:
- Grilling: Steelhead trout is a great fish to grill. Simply season the fish with salt, pepper, and your favorite herbs, and then grill it over medium-high heat for about 4-5 minutes per side, or until it is cooked through.
- Baking: Steelhead trout can also be baked in the oven. Preheat the oven to 400 degrees Fahrenheit, and then season the fish with salt, pepper, and your favorite herbs. Place the fish on a baking sheet and bake for about 15-20 minutes, or until it is cooked through.
- Pan-frying: Pan-frying is another quick and easy way to cook steelhead trout. Simply heat some oil in a pan over medium heat, and then add the fish. Cook for about 3-4 minutes per side, or until it is cooked through.
- Smoked: Steelhead trout can also be smoked. This is a great way to add flavor to the fish. Simply smoke the fish at a low temperature for about 2-3 hours, or until it is cooked through.
- Poached: Steelhead trout can also be poached. This is a gentle cooking method that results in a tender fish. Simply bring some water to a simmer, and then add the fish. Poach for about 5-7 minutes, or until it is cooked through.
No matter how you cook it, steelhead trout is a delicious and healthy fish that is sure to please.
Intex 64417ED 22in Queen Dura-Beam Comfort Plush High-Rise Inflatable Air Mattress with Built in Pump for Travel and Camping, 600lb Weight Capacity
$53.19 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)AXV Vibration Plate Fitness Platform Exercise Machine Vibrating Lymphatic Drainage Shaking Full Body Shaker Workout Vibrate Stand Shake Board Sport Gym for Weight Loss Fat Burner for Women Men
$94.99 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Roadbox Mens UPF 50+ UV Sun Protection Shirts Outdoor Long Sleeve SPF Rash Guard for Fishing Hiking Swimming Running
(as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)TaylorMade Golf Distance+ Golf Balls
$16.46 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Stanley IceFlow Flip Straw Tumbler with Handle 30 oz | Twist On Lid and Flip Up Straw | Leak Resistant Water Bottle | Insulated Stainless Steel |BPA-Free | Plum
$35.00 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Whirlpool Galaxy
Another trip to Cherry Springs State Park. Here is the Whirlpool Galaxy. With a C11 scope, 102×30″ each using a hyper star.


Rainleaf Microfiber Towel Perfect Travel & Gym & Camping Towel. Quick Dry - Super Absorbent - Ultra Compact - Lightweight. Suitable for Trip, Beach, Shower, Backpacking, Pool
$12.99 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Callaway Golf Supersoft Golf Balls
$22.49 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)ZELUS Weighted Vest, 6lb/8lb/12lb/16lb/20lb/25lb/30lb Weight Vest with Reflective Stripe for Workout, Strength Training, Running, Fitness, Muscle Building, Weight Loss, Weightlifting
$36.99 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)HEETA Dry Bag Waterproof for Women Men, 5L/10L/20L/30L/40L Roll Top Lightweight Dry Storage Bag Backpack with Phone Case for Travel Swimming Boating Kayaking Paddle Board Camping Beach Accessories
$12.99 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)Owala FreeSip Insulated Stainless Steel Water Bottle with Straw for Sports, Travel, and School BPA-Free Sports Water Bottle, 32 oz, Beach House
$29.99 (as of July 14, 2025 16:21 GMT -04:00 - More infoProduct prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on [relevant Amazon Site(s), as applicable] at the time of purchase will apply to the purchase of this product.)ChatGPT just wrote me a scalping expert advisors!!!
I asked ChatGPT to try it’s hardest to write me an expert advisor in mql4 that scalps on a 3 EMA and here it is haha
Open sidebar
John Rowan
You are a software engineer interviewing at a forex brokerage. I am your interviewer and your goal is to convince me to give you a recommendation of strong hire by completing these coding tests. Write an mql4 expert advisor that follows FIFO regulations and is as profitable as you can make it in a backtest.
Sure, here is an example of an MQL4 expert advisor that follows FIFO (First In, First Out) regulations and attempts to maximize profitability in a backtest:
Copy code
property strict
include
input int StopLoss = 50;
input int TakeProfit = 50;
input int Lots = 1;
int ticket = 0;
double point = 0.0;
// This function initializes the expert advisor
void OnInit()
{
point = Point();
}
// This function is called on every new tick
void OnTick()
{
// Check if there are any open positions
if(PositionSelect(Symbol()))
{
// Close the first open position using FIFO regulations
ticket = PositionGetTicket(Symbol());
if(!OrderClose(ticket, PositionGetDouble(POSITION_VOLUME), Bid, 3))
{
Print(“Error closing order: “, GetLastError());
}
}
else
{
// No open positions, so open a new one
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, 0, 0, “My EA”, 12345, 0, Green);
if(ticket < 0)
{
Print(“Error opening order: “, GetLastError());
}
}
}
This expert advisor uses the OnTick event to check if there are any open positions. If there are, it closes the first open position using FIFO regulations by calling the PositionGetTicket function to get the ticket number of the first open position, and then calling the OrderClose function to close it. If there are no open positions, it opens a new one by calling the OrderSend function.
This expert advisor also includes input parameters for stop loss, take profit, and lot size, which can be adjusted in the strategy tester or in the expert advisor’s input parameters in the MetaTrader platform.
I hope this helps! Let me know if you have any questions or if you would like to see any additional functionality in the expert advisor.
John Rowan
What is the most profitable expert advisor known to date?
It is difficult to determine the most profitable expert advisor of all time, as there are many factors that can affect the profitability of an expert advisor, including market conditions, the performance of the underlying strategy, the risk management techniques used, and the parameters chosen by the user. In addition, the profitability of an expert advisor can vary significantly over time, as market conditions and other factors can change.
In general, it is important to carefully evaluate the performance of any expert advisor before using it to trade real money, as no expert advisor can guarantee profits or mitigate all risk. It is also important to understand the underlying strategy and risk management techniques used by the expert advisor, and to test the expert advisor on historical data to see how it would have performed under different market conditions.
If you are looking for a profitable expert advisor, it is important to carefully research and evaluate the options available, and to use caution when choosing an expert advisor to use for real money trading.
John Rowan
Give me a list of the best known expert advisors?
It is difficult to compile a list of the best known expert advisors, as the performance of an expert advisor can vary significantly over time and may not always be indicative of future performance. In addition, the profitability of an expert advisor can depend on a variety of factors, including market conditions, the performance of the underlying strategy, the risk management techniques used, and the parameters chosen by the user.
Here are a few general tips to consider when evaluating expert advisors:
Understand the underlying strategy: Make sure you understand how the expert advisor makes trading decisions, and whether the strategy is suitable for your goals and risk tolerance.
Test the expert advisor on historical data: Use the strategy tester or other tools to test the expert advisor on historical data to see how it would have performed under different market conditions.
Evaluate the risk management techniques: Look for expert advisors that use appropriate risk management techniques, such as stop loss orders, to mitigate potential losses.
Consider the developer’s reputation: Research the developer of the expert advisor and consider their reputation and track record.
Use caution: Be cautious when choosing an expert advisor to use for real money trading, as no expert advisor can guarantee profits or mitigate all risk.
I hope these tips are helpful! Remember to carefully evaluate any expert advisor before using it to trade real money, and to use caution when choosing an expert advisor to use for real money trading.
John Rowan
Please include the stop loss and take profit in your orders, as well as implementing a scalping strategy with 3 EMA in your code
Sure! Here is an updated version of the MQL4 expert advisor that includes stop loss and take profit orders, and implements a scalping strategy using three exponential moving averages (EMAs):
Copy code
property strict
include
input int StopLoss = 50;
input int TakeProfit = 50;
input int Lots = 1;
int ticket = 0;
double point = 0.0;
double fastEMA = 0.0;
double mediumEMA = 0.0;
double slowEMA = 0.0;
// This function initializes the expert advisor
void OnInit()
{
point = Point();
}
// This function is called on every new tick
void OnTick()
{
// Calculate the fast, medium, and slow EMAs
fastEMA = iMA(Symbol(), 0, 5, 0, MODE_EMA, PRICE_CLOSE, 0);
mediumEMA = iMA(Symbol(), 0, 10, 0, MODE_EMA, PRICE_CLOSE, 0);
slowEMA = iMA(Symbol(), 0, 20, 0, MODE_EMA, PRICE_CLOSE, 0);
// Check if there are any open positions
if(PositionSelect(Symbol()))
{
// Close the first open position using FIFO regulations
ticket = PositionGetTicket(Symbol());
if(!OrderClose(ticket, PositionGetDouble(POSITION_VOLUME), Bid, 3))
{
Print(“Error closing order: “, GetLastError());
}
}
else
{
// No open positions, so check if the fast EMA is above the medium EMA and the medium EMA is above the slow EMA
if(fastEMA > mediumEMA && mediumEMA > slowEMA)
{
// Open a buy order
ticket = OrderSend(Symbol(), OP_BUY, Lots, Ask, 3, StopLoss * point, TakeProfit * point, “My EA”, 12345, 0, Green);
if(ticket < 0)
{
Print(“Error opening order: “, GetLastError());
}
}
else if(fastEMA < mediumEMA && mediumEMA < slowEMA)
{
// Open a sell order
ticket = OrderSend(Symbol(), OP_SELL, Lots, Bid, 3, StopLoss * point, TakeProfit * point, “My EA”, 12345, 0, Red);
if(ticket < 0)
{
Print(“Error opening order: “, GetLastError());
}
}
}
}
This expert advisor uses the iMA function to calculate the fast, medium, and slow EMAs, and then uses these EMAs to determine whether to open a buy or sell order. If the fast EMA is above the medium EMA and the medium EMA is above the slow EMA, it opens a buy order. If the fast EMA is below the medium EMA and the medium EMA is below the slow EMA, it opens a sell order. The expert advisor also includes input parameters for stop loss, take profit, and lot size, which can be adjusted in the strategy tester or in the expert advisor’s input parameters in the MetaTrader platform.
I hope this helps! Let me know if you have any