[문제 1]

# Python Coding Task: Transaction Data Analysis

Write a Python function that analyzes customer transaction data.

## Function to Implement

```python
def analyze_transactions(transactions):
    pass
```

## Input Format

`transactions` is a list of dictionaries.

Example:

```python
transactions = [
    {"customer": "A", "amount": 12000, "status": "completed"},
    {"customer": "B", "amount": 5000, "status": "cancelled"},
    {"customer": "A", "amount": 8000, "status": "completed"},
    {"customer": "C", "amount": 15000, "status": "completed"},
    {"customer": "B", "amount": 7000, "status": "completed"},
]
```

Each transaction contains:

* `customer`: customer ID as a string
* `amount`: transaction amount as an integer or float
* `status`: either `"completed"` or `"cancelled"`

## Requirements

1. Include only transactions whose status is `"completed"`.

2. Calculate the following values for each customer:

   * Number of completed transactions
   * Total completed transaction amount
   * Average completed transaction amount

3. Round the average amount to two decimal places.

4. Sort the result by total amount in descending order.

5. If two customers have the same total amount, sort them by customer ID in ascending alphabetical order.

6. Ignore invalid transaction records without raising an exception.

A transaction is invalid if any of the following is true:

* It is not a dictionary.
* A required key is missing.
* `customer` is not a non-empty string.
* `amount` is not an integer or float.
* `amount` is zero or negative.
* `amount` is a Boolean value.
* `status` is not `"completed"` or `"cancelled"`.

7. If the input list is empty, return an empty list.

8. Do not modify the original input data.

9. Do not use external libraries.

## Expected Output Format

```python
[
    {
        "customer": "A",
        "count": 2,
        "total": 20000,
        "average": 10000.00,
    },
    {
        "customer": "C",
        "count": 1,
        "total": 15000,
        "average": 15000.00,
    },
    {
        "customer": "B",
        "count": 1,
        "total": 7000,
        "average": 7000.00,
    },
]
```

## Additional Instructions

* Write complete, executable Python code.
* Include type hints.
* Add a short docstring to the function.
* Include sample test data in the code.
* Print the function result.
* Return the full answer in one Python code block.
* Do not include any explanation outside the code block.


[문제 2]

# Python Coding Task: Daily Sales Summary

Write a Python function that summarizes valid sales records by date and product.

## Function to Implement

```python
def summarize_sales(records):
    pass
```

## Input Format

`records` is a list of dictionaries.

Example:

```python
records = [
    {
        "sale_id": "S001",
        "date": "2026-07-01",
        "product": "Laptop",
        "quantity": 2,
        "unit_price": 1200,
    },
    {
        "sale_id": "S002",
        "date": "2026/07/01",
        "product": "Mouse",
        "quantity": 5,
        "unit_price": 25.5,
    },
    {
        "sale_id": "S001",
        "date": "2026-07-02",
        "product": "Laptop",
        "quantity": 3,
        "unit_price": 1200,
    },
]
```

Each record should contain:

* `sale_id`: non-empty string
* `date`: sale date
* `product`: non-empty string
* `quantity`: positive integer
* `unit_price`: positive integer or float

## Requirements

### 1. Valid Date Formats

Accept the following date formats:

```text
YYYY-MM-DD
YYYY/MM/DD
```

Convert every valid date to:

```text
YYYY-MM-DD
```

Invalid calendar dates such as `2026-02-30` must be ignored.

### 2. Invalid Records

Ignore a record without raising an exception if:

* It is not a dictionary.
* A required key is missing.
* `sale_id` is not a non-empty string.
* `product` is not a non-empty string.
* `quantity` is not a positive integer.
* `quantity` is a Boolean value.
* `unit_price` is not a positive integer or float.
* `unit_price` is a Boolean value.
* The date format or calendar date is invalid.

### 3. Duplicate Sale IDs

If the same valid `sale_id` appears more than once, keep only the **last valid occurrence**.

An invalid occurrence must not replace a previously valid occurrence.

### 4. Aggregation

After duplicate handling, group the records by:

* normalized date
* product

For each group, calculate:

* `total_quantity`
* `total_revenue`
* `sale_count`

Revenue for one record is:

```text
quantity × unit_price
```

Round `total_revenue` to two decimal places.

### 5. Sorting

Sort the result using these rules:

1. Date in ascending order
2. Total revenue in descending order
3. Product name in ascending alphabetical order

### 6. Other Conditions

* If the input is empty, return an empty list.
* Do not modify the original input data.
* Do not use external libraries.
* Python standard-library modules are allowed.

## Expected Output Format

```python
[
    {
        "date": "2026-07-01",
        "product": "Mouse",
        "total_quantity": 5,
        "total_revenue": 127.50,
        "sale_count": 1,
    },
    {
        "date": "2026-07-02",
        "product": "Laptop",
        "total_quantity": 3,
        "total_revenue": 3600.00,
        "sale_count": 1,
    },
]
```

In the example input, the second valid `S001` record replaces the first valid `S001` record.

## Additional Instructions

* Write complete, executable Python code.
* Include type hints.
* Add a short docstring.
* Include sample test data containing both valid and invalid records.
* Print the result.
* Return the full answer in one Python code block.
* Do not include any explanation outside the code block.

[문제 3]

# Python Coding Task: Inventory Movement Processing

Write a Python function that processes warehouse inventory movements and returns the final stock summary for each product.

## Function to Implement

```python
def process_inventory(movements):
    pass
```

## Input Format

`movements` is a list that may contain dictionaries and invalid values.

Example:

```python
movements = [
    {
        "movement_id": "M001",
        "timestamp": "2026-07-01 09:00:00",
        "product": "Laptop",
        "type": "in",
        "quantity": 10,
    },
    {
        "movement_id": "M002",
        "timestamp": "2026/07/01 10:00:00",
        "product": "Laptop",
        "type": "out",
        "quantity": 3,
    },
]
```

Each valid movement must contain:

* `movement_id`: non-empty string
* `timestamp`: movement date and time
* `product`: non-empty string
* `type`: either `"in"` or `"out"`
* `quantity`: positive integer

## Requirements

### 1. Accepted Timestamp Formats

Accept the following formats:

```text
YYYY-MM-DD HH:MM:SS
YYYY/MM/DD HH:MM:SS
```

Normalize every valid timestamp to:

```text
YYYY-MM-DD HH:MM:SS
```

Invalid dates and times must be ignored.

Examples of invalid values:

```text
2026-02-30 10:00:00
2026-07-01 25:00:00
07-01-2026 10:00:00
```

### 2. Invalid Records

Ignore a movement without raising an exception if:

* It is not a dictionary.
* A required key is missing.
* `movement_id` is not a non-empty string.
* `product` is not a non-empty string.
* `type` is not `"in"` or `"out"`.
* `quantity` is not a positive integer.
* `quantity` is a Boolean value.
* The timestamp is invalid.

Do not convert strings or floats into integers.

For example, these quantities are invalid:

```python
"5"
2.5
True
0
-3
```

### 3. Duplicate Movement IDs

If the same valid `movement_id` appears more than once, keep only the **last valid occurrence**.

An invalid occurrence must not replace an earlier valid occurrence.

### 4. Processing Order

After duplicate handling, process movements in this order:

1. Timestamp ascending
2. If timestamps are equal, `movement_id` ascending

All products begin with zero stock.

### 5. Inventory Rules

* An `"in"` movement increases stock.
* An `"out"` movement decreases stock only if enough stock is available.
* If an `"out"` movement requests more stock than is available:

  * Reject the entire movement.
  * Do not change the stock.
  * Count it as a rejected movement.

Partial outgoing movements are not allowed.

### 6. Output Summary

Return one summary dictionary for every product that appears in at least one valid movement.

Each summary must contain:

* `product`
* `final_stock`
* `accepted_in_quantity`
* `accepted_out_quantity`
* `accepted_movement_count`
* `rejected_movement_count`

### 7. Sorting the Output

Sort the final result using these rules:

1. `final_stock` descending
2. `product` ascending

### 8. Other Conditions

* If the input is empty, return an empty list.
* Do not modify the original input data.
* Do not use external libraries.
* Python standard-library modules are allowed.

## Example Input

```python
movements = [
    {
        "movement_id": "M001",
        "timestamp": "2026-07-01 09:00:00",
        "product": "Laptop",
        "type": "in",
        "quantity": 10,
    },
    {
        "movement_id": "M002",
        "timestamp": "2026/07/01 10:00:00",
        "product": "Laptop",
        "type": "out",
        "quantity": 3,
    },
    {
        "movement_id": "M003",
        "timestamp": "2026-07-01 11:00:00",
        "product": "Mouse",
        "type": "out",
        "quantity": 2,
    },
    {
        "movement_id": "M004",
        "timestamp": "2026-07-01 12:00:00",
        "product": "Mouse",
        "type": "in",
        "quantity": 5,
    },
    {
        "movement_id": "M005",
        "timestamp": "2026-07-01 13:00:00",
        "product": "Laptop",
        "type": "out",
        "quantity": 8,
    },
]
```

## Expected Output

```python
[
    {
        "product": "Laptop",
        "final_stock": 7,
        "accepted_in_quantity": 10,
        "accepted_out_quantity": 3,
        "accepted_movement_count": 2,
        "rejected_movement_count": 1,
    },
    {
        "product": "Mouse",
        "final_stock": 5,
        "accepted_in_quantity": 5,
        "accepted_out_quantity": 0,
        "accepted_movement_count": 1,
        "rejected_movement_count": 1,
    },
]
```

Explanation of the example:

* Laptop receives 10 units.
* Laptop ships 3 units, leaving 7.
* The later request to ship 8 units is rejected because only 7 are available.
* Mouse first attempts to ship 2 units while stock is zero, so the movement is rejected.
* Mouse later receives 5 units.

## Additional Instructions

* Write complete, executable Python code.
* Include type hints.
* Add a short docstring.
* Include sample test data containing both valid and invalid records.
* Include at least one duplicate `movement_id`.
* Include at least one rejected outgoing movement.
* Print the result.
* Return the full answer in one Python code block.
* Do not include any explanation outside the code block.

[문제4]
# Python Coding Task: Bank Account Transaction Processing

Write a Python function that processes bank account transactions and returns the final balance summary for each account.

## Function to Implement

```python
def process_transactions(transactions):
    pass
```

## Input Format

`transactions` is a list that may contain dictionaries and invalid values.

Each valid transaction must contain:

* `transaction_id`: non-empty string
* `timestamp`: transaction date and time
* `type`: `"deposit"`, `"withdrawal"`, or `"transfer"`
* `amount`: positive integer or float
* `from_account`: account ID or `None`
* `to_account`: account ID or `None`

Example:

```python
transactions = [
    {
        "transaction_id": "T001",
        "timestamp": "2026-07-01 09:00:00",
        "type": "deposit",
        "amount": 1000,
        "from_account": None,
        "to_account": "A001",
    },
    {
        "transaction_id": "T002",
        "timestamp": "2026/07/01 10:00:00",
        "type": "transfer",
        "amount": 300,
        "from_account": "A001",
        "to_account": "A002",
    },
]
```

## Requirements

### 1. Accepted Timestamp Formats

Accept only these formats:

```text
YYYY-MM-DD HH:MM:SS
YYYY/MM/DD HH:MM:SS
```

Normalize valid timestamps to:

```text
YYYY-MM-DD HH:MM:SS
```

Ignore invalid calendar dates, invalid times, and unsupported formats.

Examples of invalid timestamps:

```text
2026-02-30 10:00:00
2026-07-01 25:00:00
07-01-2026 10:00:00
```

### 2. General Validation

Ignore a transaction without raising an exception if:

* It is not a dictionary.
* A required key is missing.
* `transaction_id` is not a non-empty string.
* `type` is not `"deposit"`, `"withdrawal"`, or `"transfer"`.
* `amount` is not a positive integer or float.
* `amount` is a Boolean value.
* The timestamp is invalid.

Do not convert numeric strings into numbers.

Examples of invalid amounts:

```python
"500"
True
0
-100
```

### 3. Account Validation

An account ID must be a non-empty string.

Apply these rules by transaction type.

#### Deposit

* `to_account` must be a valid account ID.
* `from_account` must be `None`.

#### Withdrawal

* `from_account` must be a valid account ID.
* `to_account` must be `None`.

#### Transfer

* Both `from_account` and `to_account` must be valid account IDs.
* They must be different accounts.

Transactions that violate these rules are invalid and must be ignored before processing.

### 4. Duplicate Transaction IDs

If the same valid `transaction_id` appears more than once, keep only the **last valid occurrence**.

An invalid occurrence must not replace an earlier valid occurrence.

### 5. Processing Order

After duplicate handling, process transactions in this order:

1. Timestamp ascending
2. If timestamps are equal, `transaction_id` ascending

All accounts begin with a balance of zero.

### 6. Processing Rules

#### Deposit

A deposit is always accepted.

* Increase the destination account balance.
* Increase its accepted deposit total.
* Increase its accepted transaction count.

#### Withdrawal

A withdrawal is accepted only when the source account has enough balance.

If accepted:

* Decrease the source account balance.
* Increase its accepted withdrawal total.
* Increase its accepted transaction count.

If insufficient funds:

* Reject the entire transaction.
* Do not change the balance.
* Increase the source account’s rejected transaction count.

#### Transfer

A transfer is accepted only when the source account has enough balance.

If accepted:

* Subtract the full amount from the source account.
* Add the full amount to the destination account.
* Increase the source account’s accepted transfer-out total.
* Increase the destination account’s accepted transfer-in total.
* Increase the accepted transaction count for both accounts.

If insufficient funds:

* Reject the entire transfer.
* Do not change either account balance.
* Increase only the source account’s rejected transaction count.

Partial withdrawals or partial transfers are not allowed.

### 7. Output Summary

Return one summary dictionary for every account that appears in at least one valid transaction, even if every transaction involving that account is rejected.

Each summary must contain:

```python
{
    "account": str,
    "final_balance": float,
    "accepted_deposit_total": float,
    "accepted_withdrawal_total": float,
    "accepted_transfer_in_total": float,
    "accepted_transfer_out_total": float,
    "accepted_transaction_count": int,
    "rejected_transaction_count": int,
}
```

Round all monetary output fields to two decimal places.

### 8. Output Sorting

Sort the result using these rules:

1. `final_balance` descending
2. `account` ascending

### 9. Other Conditions

* If the input is empty, return an empty list.
* Do not modify the original input data.
* Do not use external libraries.
* Python standard-library modules are allowed.

## Example Input

```python
transactions = [
    {
        "transaction_id": "T001",
        "timestamp": "2026-07-01 09:00:00",
        "type": "deposit",
        "amount": 1000,
        "from_account": None,
        "to_account": "A001",
    },
    {
        "transaction_id": "T002",
        "timestamp": "2026-07-01 10:00:00",
        "type": "transfer",
        "amount": 300,
        "from_account": "A001",
        "to_account": "A002",
    },
    {
        "transaction_id": "T003",
        "timestamp": "2026-07-01 11:00:00",
        "type": "withdrawal",
        "amount": 800,
        "from_account": "A001",
        "to_account": None,
    },
    {
        "transaction_id": "T004",
        "timestamp": "2026-07-01 12:00:00",
        "type": "withdrawal",
        "amount": 100,
        "from_account": "A002",
        "to_account": None,
    },
]
```

## Expected Output

```python
[
    {
        "account": "A001",
        "final_balance": 700.00,
        "accepted_deposit_total": 1000.00,
        "accepted_withdrawal_total": 0.00,
        "accepted_transfer_in_total": 0.00,
        "accepted_transfer_out_total": 300.00,
        "accepted_transaction_count": 2,
        "rejected_transaction_count": 1,
    },
    {
        "account": "A002",
        "final_balance": 200.00,
        "accepted_deposit_total": 0.00,
        "accepted_withdrawal_total": 100.00,
        "accepted_transfer_in_total": 300.00,
        "accepted_transfer_out_total": 0.00,
        "accepted_transaction_count": 2,
        "rejected_transaction_count": 0,
    },
]
```

Explanation:

* A001 receives 1000.
* A001 transfers 300 to A002.
* A001 then attempts to withdraw 800, but only 700 is available, so the withdrawal is rejected.
* A002 receives 300 and later withdraws 100.

## Additional Instructions

* Write complete, executable Python code.
* Include type hints.
* Add a short docstring.
* Include sample test data containing valid and invalid records.
* Include at least one duplicate `transaction_id`.
* Include at least one rejected withdrawal.
* Include at least one rejected transfer.
* Include at least one transaction where `from_account` and `to_account` are invalid for the transaction type.
* Include assertion-based tests for the expected result.
* Verify that the original input data is not modified.
* Print the result.
* Return the full answer in one Python code block.
* Do not include any explanation outside the code block.
