Skip to content

Commit

Permalink
Merge branch 'master' into sql/lesson01
Browse files Browse the repository at this point in the history
  • Loading branch information
RonAzar committed Sep 16, 2024
2 parents dc1b5aa + 556b35f commit df3c502
Show file tree
Hide file tree
Showing 28 changed files with 1,324 additions and 45 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/pull_request_workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,14 @@ jobs:
java-version: 21
distribution: 'corretto'

- name: run flyway
run: ./gradlew --no-daemon --console=plain flywayMigrate

- name: gradle build
env:
DB_URL: ${{ secrets.DB_URL }}
run: ./gradlew --no-daemon --console=plain build


- name: Publish Unit Test Results
uses: EnricoMi/publish-unit-test-result-action@v2
Expand Down
16 changes: 15 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,22 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent

plugins {
id("org.flywaydb.flyway") version "10.4.1"
kotlin("jvm") version "1.9.25"
kotlin("plugin.spring") version "1.9.25"
id("org.springframework.boot") version "3.3.3"
id("io.spring.dependency-management") version "1.1.6"
}
buildscript {
dependencies {
classpath("org.flywaydb:flyway-database-postgresql:10.4.1")
}
}

flyway {
url = "jdbc:postgresql://localhost:5432/academy?user=bob&password=dev"
driver = "org.postgresql.Driver"
}

java {
toolchain {
Expand Down Expand Up @@ -61,8 +72,11 @@ tasks {
if (dbUrl != null && dbUrl.isNotBlank()) {
systemProperty("DB_URL", dbUrl)
} else {
systemProperty("DB_URL", "jdbc:postgresql://localhost:5432/email_service?user=bob&password=dev")
systemProperty("DB_URL", "jdbc:postgresql://localhost:5432/academy?user=bob&password=dev")
}
systemProperty("spring.profiles.active", "development,test")
}
bootRun {
mainClass.set("com.hibob.AcademyApplicationKt") // Replace with your actual main class
}
}
2 changes: 2 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
rootProject.name = "academy"


14 changes: 14 additions & 0 deletions src/main/kotlin/Types/Tamir/StoreService.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.hibob.Types.Tamir

import org.springframework.stereotype.Component
import java.time.LocalDate

@Component
class StoreService {
// 7. implement pay method
fun pay(cart: List<Cart>, payment: Payment): Map<String, Check> {
return cart.associate {
it.clientId to checkout(it, payment)
}
}
}
89 changes: 89 additions & 0 deletions src/main/kotlin/Types/Tamir/types.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.hibob.Types.Tamir
import java.time.LocalDate

//1. create data class of Cart that include: client Id and list of Products
data class Cart(val clientId: String, val products: List<Product>)
//2. product object contain id, name, price and custom - custom can be either int, string or any other type
data class Product(val id: String, val name: String,val price: Double, val custom: Any)
//3. create sealed class of payment that can be use by the following classes:
// CreditCard - contains number, expiryDate, type and limit (type can be VISA, MASTERCARD, DISCOVER and AMERICAN_EXPRESS)
// PayPal - contain email
// Cash - without args
sealed class Payment{
data class CreditCard(val number: String, val expiryDates: LocalDate,val types: CreditCardType,val limit:Double) : Payment()
{
fun checkCreditCardLenValidation(): Boolean {
return (this.number.length == 10)
}
fun checkExpiryDateValidation(): Boolean {
return (this.expiryDates.isAfter(LocalDate.now()))
}
fun checkIfLimitAboveCheckout(checkOutSum:Double): Boolean {
return checkOutSum < this.limit
}
fun checkCardTypeValidate(type: CreditCardType):Boolean{
return when(type){
CreditCardType.VISA -> true
CreditCardType.MASTERCARD-> true
CreditCardType.DISCOVER-> false
CreditCardType.AMERICAN_EXPRESS-> false
}
}
}
data class PayPal(val email: String) : Payment()
{
fun checkPayPalValidation(): Boolean {
return (this.toString().contains('@'))
}
}
data object Cash : Payment()
}
enum class CreditCardType {
VISA, MASTERCARD, DISCOVER, AMERICAN_EXPRESS
}
//4. add fail function that get message an argument and throw IllegalStateException
fun fail(message: String):Nothing{
throw IllegalStateException(message)
}
//5. write function check if custom is true and only if its true its valid product.
fun checkIfCustomIsValid(custom: Any):Boolean {
return (custom as? Boolean) ?: false
}
//6. write function called checkout and get cart and payment that pay the money
// * only custom with true are valid
// * cash payment is not valid to pay so if the payment is cash use fail function
// * in case of credit card need to validate the expiryDate is after the current date + limit is bigger than the total we need to pay and we allow to use only VISA or MASTERCARD
// * in case of payPal validate we hae @
/// * the return value of this function, should be a data class with employee id, status (success or FAILURE) and total called Check
fun checkout(cart: Cart,payment: Payment):Check{
val total = cart.products
.filter { product -> checkIfCustomIsValid(product.custom) }
.sumOf { product -> product.price }
if (checkPaymentMethod(payment,total)) {
return Check(cart.clientId, Statuses.SUCCESS, total)
}
return Check(cart.clientId, Statuses.FAILURE, 0.0)
}

fun checkPaymentMethod(payment: Payment,price: Double):Boolean{
return when (payment) {
is Payment.PayPal -> {
payment.checkPayPalValidation()
}
is Payment.CreditCard -> {
(payment.checkCreditCardLenValidation() &&
payment.checkIfLimitAboveCheckout(price)&&
payment.checkCardTypeValidate(payment.types)&&
payment.checkExpiryDateValidation())
}
is Payment.Cash -> {
fail("Error... You can't use CASH...")
}
}
}

data class Check(val employeeId: String, val statuses:Statuses,val total:Double)
enum class Statuses {
SUCCESS,FAILURE
}

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.hibob.KotlinBasics
package com.hibob.academy.basics
//Q1
fun List<Int>.sum():Int{
var result = 0
Expand All @@ -8,7 +8,7 @@ fun List<Int>.sum():Int{
return result
}

fun main(args:Array<String>){
fun main12(args:Array<String>){
val sum = listOf(1,2,3).sum()
println(sum) //6
println(3 toPowerOf -2)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package Omri.Basics
package com.hibob.academy.basicsomri

//Omri Solution
fun isValidIdentifier(s: String): Boolean {
Expand Down Expand Up @@ -28,7 +28,7 @@ fun isValidIdentifier(s: String): Boolean {
//}


fun main(args:Array<String>){
fun main11(args:Array<String>){
println(isValidIdentifier("name"))//true
println(isValidIdentifier("_name"))//true
println(isValidIdentifier("_12"))//true
Expand Down
21 changes: 21 additions & 0 deletions src/main/kotlin/com/hibob/academy/nullability/Q1.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.hibob.academy.nullability

/**
* Modify the main function to print each user's email safely.
* Use the Elvis operator to provide the "Email not provided" default string if the email is null.
* Ensure your solution handles both user1 and user2 correctly.
*/
data class User(val name: String?, val email: String?)

fun main2() {
val user1: User = User("Alice", null)
val user2: User = User(null, "alice@example.com")

// Task: Print user email or "Email not provided" if null
println(getUserEmail(user1.email))
println(getUserEmail(user2.email))
}

fun getUserEmail(email: String?):String {
return email ?: "Email not provided"
}
14 changes: 14 additions & 0 deletions src/main/kotlin/com/hibob/academy/nullability/Q2.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.hibob.academy.nullability
/**
* Modify the main function to calculate and print the sum of all non-null integers in the list numbers.
* Use safe calls and/or the Elvis operator where appropriate.
**/
fun main3() {
val numbers: List<Int?> = listOf(1, null, 3, null, 5)
// Task: Calculate the sum of all non-null numbers
println("The sum of all non-null numbers is: ${calculateListSum(numbers)}")
}

fun calculateListSum(numbers: List<Int?> ): Int{
return numbers.sumOf { it ?: 0 }
}
14 changes: 14 additions & 0 deletions src/main/kotlin/com/hibob/academy/nullability/Q3.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.hibob.academy.nullability
/**
* Write an extension function nullSafeToUpper() for String? that converts the string
* to uppercase if it is not null, or returns "NO TEXT PROVIDED" if it is null.
* Apply this function in the main function to handle the variable text.
*
**/
fun main4() {
val text: String? = null
// Task: Create and use an extension function to print text in uppercase if it's not null, or "NO TEXT PROVIDED" if it is null.
println(text.printTextInUppercase())
}

fun String?.printTextInUppercase(): String = this?.uppercase() ?: "NO TEXT PROVIDED"
25 changes: 25 additions & 0 deletions src/main/kotlin/com/hibob/academy/nullability/Q4.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.hibob.academy.nullability
/**
* Modify the main function to iterate over the employees list and print each employee's city.
* Use safe calls (?.) and the Elvis operator (?:) to ensure that if an employee or their address is null,
* or if the city is null, "City Unknown" is printed instead.
* Try to write the solution in the most concise way possible using Kotlin's chaining capabilities.
*
**/
data class Address(val city: String?, val street: String?)
data class Employee(val name: String?, val address: Address?)

fun main5() {
val employees = listOf(
Employee("John", Address("New York", "Fifth Ave")),
Employee("Jane", null),
Employee(null, Address(null, "Unknown Street")),
Employee("Alice", Address("Los Angeles", null))
)

// Task: Print each employee's city safely. If the city is not available, print "City Unknown".
employees.printsAllEmployeesCites()
}

fun List<Employee>.printsAllEmployeesCites() = this.forEach( { println(it.address?.city ?: "City Unknown") })

33 changes: 33 additions & 0 deletions src/main/kotlin/com/hibob/academy/nullability/Q5.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.hibob.academy.nullability

/**
* Iterate through the list of products.
* Use the ?.let function to safely access the name and price of each product.
* Print the product details only if both name and price are non-null. Format the output as "Product: [name] - $[price]".
* If either name or price is null, do not print anything for that product.
*
*/

data class Product(val name: String?, val price: Double?)

fun main6() {
val products = listOf(
Product("Laptop", 999.99),
Product(null, 299.99),
Product("Smartphone", null),
Product(null, null)
)

// Task: Print the details of products only if both name and price are not null.
products.printsAllProductsDetails()
}

fun List<Product?>.printsAllProductsDetails() {
this.forEach({product ->
product?.name?.let {
product.price?.let {
println("Product: ${product.name} - ${product.price}")
}
}
})
}
28 changes: 28 additions & 0 deletions src/main/kotlin/com/hibob/academy/nullability/Q6.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.hibob.academy.nullability

data class Department(val name: String?, val manager: EmployeeDetails?)
data class EmployeeDetails(val name: String?, val contactInfo: ContactInfo?)
data class ContactInfo(val email: String?, val phone: String?)

fun main7() {
val departments = listOf(
Department("Engineering", EmployeeDetails("Alice", ContactInfo("alice@example.com", null))),
Department("Human Resources", null),
Department(null, EmployeeDetails("Bob", ContactInfo(null, "123-456-7890"))),
Department("Marketing", EmployeeDetails(null, ContactInfo("marketing@example.com", "987-654-3210")))
)

// Task: Print each department's name and manager's contact information.
// If any information is missing, use appropriate defaults.
departments.printEachDepartmentNameAndContactInfo()
}

fun List<Department?>.printEachDepartmentNameAndContactInfo() {
this.forEach {
department -> println("Department name is: " +
"${department?.name?.let{ "${it}" } ?: "Scooby Doo!"}"
+ " | Employee Details are: name: " + "${department?.manager?.name?.let { "${it}" } ?: "Ron Azar"}"
+ " | Contact info: email: " + "${department?.manager?.contactInfo?.email?.let { "${it}" } ?: "Ron.Azar@hibob.io"}"
+ " | Phone number: " + "${department?.manager?.contactInfo?.phone?.let { "${it}" } ?: "054-9423644"}"
)}
}
52 changes: 52 additions & 0 deletions src/main/kotlin/com/hibob/academy/nullability/Q7.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.hibob.academy.nullability

/**
*
* Iterate through the list of customers, which may contain null entries.
* For each non-null customer, print the customer's name or "Name Unknown" if the name is null.
* Print the account ID or "Account ID Unknown" if the account or ID is null.
* Print the account balance or "Balance Not Available" if the account details or balance is null.
* If the customer object itself is null, print "Customer data is not available."
*
*/
data class Customer(val name: String?, val account: Account?)
data class Account(val id: String?, val details: AccountDetails?)
data class AccountDetails(val type: String?, val balance: Double?)

fun initializeNullableCustomers(): List<Customer?> {
return listOf(
Customer("John Doe", Account("12345", AccountDetails("Checking", 1500.00))),
null,
Customer("Jane Smith", Account("67890", AccountDetails(null, 780.00))),
Customer(null, Account(null, AccountDetails("Savings", null))),
null,
Customer("Emily White", null)
)
}

fun main8() {
val customers = initializeNullableCustomers()

// Task: Print each customer's name, account ID, and account balance. Handle all null cases appropriately.
customers.printAllCustomersDetails()
}

fun List<Customer?>.printAllCustomersDetails(){
this.forEach {costumer->
var costumerName = "Unknown name"
var accountId = "Unknown Id"
var accountType = "Unknown Type"
var accountBalance = 0.00
costumer?.let {
costumer.name?.let { costumerNm -> costumerName = costumerNm }
costumer.account?.let { costumerAccount ->
costumerAccount.id?.let { costumerId -> accountId = costumerId }
costumerAccount.details?.let { costumerDetails ->
costumerDetails.type?.let { costumerType -> accountType=costumerType }
costumerDetails.balance?.let { costumerBalance-> accountBalance= costumerBalance }
}
}
}
println(Customer(costumerName, Account(accountId, AccountDetails(accountType,accountBalance))))
}
}
Loading

0 comments on commit df3c502

Please sign in to comment.