Pipeline controller: plan 2 (hard +, error +50 %), backlog throttle, 2 trajectory workers, stop rules, summaries every 50; budget reserve

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Kral
2026-10-05 13:35:54 +02:00
parent 1c4667a0fc
commit 13360292dd
781 changed files with 50211 additions and 22 deletions

View File

@@ -0,0 +1,66 @@
CLASS {{p}}rideshare_split DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_distance TYPE i.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate_total
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS calculate_share
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_share) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_base_fee TYPE ty_amount VALUE '3.00',
c_fee_per_km TYPE ty_amount VALUE '0.40',
c_detour_fee TYPE ty_amount VALUE '1.20',
c_min_share TYPE ty_amount VALUE '1.50'.
METHODS distance_fee
IMPORTING iv_distance_km TYPE ty_distance
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS detour_fee
IMPORTING iv_passengers TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}rideshare_split IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD calculate_total.
IF iv_passengers < 1.
RETURN.
ENDIF.
rv_total = c_base_fee - distance_fee( iv_distance_km ) + detour_fee( iv_passengers ).
ENDMETHOD.
METHOD calculate_share.
IF iv_passengers < 1.
RETURN.
ENDIF.
DATA(lv_total) = calculate_total( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers ).
DATA lv_share TYPE p LENGTH 15 DECIMALS 5.
lv_share = lv_total / iv_passengers.
rv_share = round( val = lv_share dec = 2 ).
IF rv_share < c_min_share.
rv_share = c_min_share.
ENDIF.
ENDMETHOD.
METHOD distance_fee.
IF iv_distance_km > 0.
rv_fee = c_fee_per_km * iv_distance_km.
ENDIF.
ENDMETHOD.
METHOD detour_fee.
rv_fee = c_detour_fee * ( iv_passengers - 1 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,66 @@
CLASS {{p}}rideshare_split DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_distance TYPE i.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate_total
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS calculate_share
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_share) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_base_fee TYPE ty_amount VALUE '3.00',
c_fee_per_km TYPE ty_amount VALUE '0.40',
c_detour_fee TYPE ty_amount VALUE '1.20',
c_min_share TYPE ty_amount VALUE '1.50'.
METHODS distance_fee
IMPORTING iv_distance_km TYPE ty_distance
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS detour_fee
IMPORTING iv_passengers TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}rideshare_split IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD calculate_total.
IF iv_passengers < 1.
RETURN.
ENDIF.
rv_total = c_base_fee + distance_fee( iv_distance_km ) + detour_fee( iv_passengers ).
ENDMETHOD.
METHOD calculate_share.
IF iv_passengers >= 1.
RETURN.
ENDIF.
DATA(lv_total) = calculate_total( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers ).
DATA lv_share TYPE p LENGTH 15 DECIMALS 5.
lv_share = lv_total / iv_passengers.
rv_share = round( val = lv_share dec = 2 ).
IF rv_share < c_min_share.
rv_share = c_min_share.
ENDIF.
ENDMETHOD.
METHOD distance_fee.
IF iv_distance_km > 0.
rv_fee = c_fee_per_km * iv_distance_km.
ENDIF.
ENDMETHOD.
METHOD detour_fee.
rv_fee = c_detour_fee * ( iv_passengers - 1 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,66 @@
CLASS {{p}}rideshare_split DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_distance TYPE i.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate_total
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS calculate_share
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_share) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_base_fee TYPE ty_amount VALUE '3.00',
c_fee_per_km TYPE ty_amount VALUE '0.40',
c_detour_fee TYPE ty_amount VALUE '1.20',
c_min_share TYPE ty_amount VALUE '1.50'.
METHODS distance_fee
IMPORTING iv_distance_km TYPE ty_distance
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS detour_fee
IMPORTING iv_passengers TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}rideshare_split IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD calculate_total.
IF iv_passengers < 1.
RETURN.
ENDIF.
rv_total = c_base_fee + distance_fee( iv_distance_km ) + detour_fee( iv_passengers ).
ENDMETHOD.
METHOD calculate_share.
IF iv_passengers < 1.
RETURN.
ENDIF.
DATA(lv_total) = calculate_total( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers ).
DATA lv_share TYPE p LENGTH 15 DECIMALS 5.
lv_share = lv_total / iv_passengers.
rv_share = round( val = lv_share dec = 2 ).
IF rv_share < c_min_share.
rv_share = c_min_share.
ENDIF.
ENDMETHOD.
METHOD distance_fee.
IF iv_distance_km <= 0.
rv_fee = c_fee_per_km * iv_distance_km.
ENDIF.
ENDMETHOD.
METHOD detour_fee.
rv_fee = c_detour_fee * ( iv_passengers - 1 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,66 @@
CLASS {{p}}rideshare_split DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_distance TYPE i.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate_total
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS calculate_share
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_share) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_base_fee TYPE ty_amount VALUE '3.00',
c_fee_per_km TYPE ty_amount VALUE '0.40',
c_detour_fee TYPE ty_amount VALUE '1.20',
c_min_share TYPE ty_amount VALUE '1.50'.
METHODS distance_fee
IMPORTING iv_distance_km TYPE ty_distance
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS detour_fee
IMPORTING iv_passengers TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}rideshare_split IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD calculate_total.
IF iv_passengers < 1.
RETURN.
ENDIF.
rv_total = c_base_fee + distance_fee( iv_distance_km ) + detour_fee( iv_passengers ).
ENDMETHOD.
METHOD calculate_share.
IF iv_passengers < 1.
RETURN.
ENDIF.
DATA(lv_total) = calculate_total( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers ).
DATA lv_share TYPE p LENGTH 15 DECIMALS 5.
lv_share = lv_total / iv_passengers.
rv_share = round( val = lv_share dec = 2 ).
IF rv_share < c_min_share.
rv_share = c_min_share.
ENDIF.
ENDMETHOD.
METHOD distance_fee.
IF iv_distance_km > 0.
rv_fee = c_fee_per_km / iv_distance_km.
ENDIF.
ENDMETHOD.
METHOD detour_fee.
rv_fee = c_detour_fee * ( iv_passengers - 1 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,24 @@
{
"id": "G1023",
"pool": "train",
"object_type": "CLAS",
"category": "A",
"attempts": [
{
"stage": "validate",
"oracle": 88.5,
"null": 0
},
{
"stage": "validate",
"oracle": 100.0,
"null": 0,
"mutation": {
"valid": 5,
"killed": 4,
"ok": true
}
}
],
"accepted": true
}

View File

@@ -0,0 +1,93 @@
CLASS {{p}}t21_hidden DEFINITION PUBLIC FINAL CREATE PUBLIC
FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}rideshare_split.
METHODS setup.
METHODS assert_split
IMPORTING iv_distance_km TYPE {{p}}rideshare_split=>ty_distance
iv_passengers TYPE i
iv_exp_total TYPE {{p}}rideshare_split=>ty_amount
iv_exp_share TYPE {{p}}rideshare_split=>ty_amount.
METHODS no_passengers FOR TESTING.
METHODS negative_passengers FOR TESTING.
METHODS single_passenger FOR TESTING.
METHODS distance_and_detour FOR TESTING.
METHODS negative_distance FOR TESTING.
METHODS rounds_half_away FOR TESTING.
METHODS minimum_share FOR TESTING.
METHODS minimum_boundary FOR TESTING.
METHODS long_ride FOR TESTING.
METHODS two_passengers FOR TESTING.
ENDCLASS.
CLASS {{p}}t21_hidden IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}rideshare_split( ).
ENDMETHOD.
METHOD assert_split.
cl_abap_unit_assert=>assert_equals(
exp = iv_exp_total
act = mo_cut->calculate_total( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers )
msg = |total, { iv_distance_km } km, { iv_passengers } passengers| ).
cl_abap_unit_assert=>assert_equals(
exp = iv_exp_share
act = mo_cut->calculate_share( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers )
msg = |share, { iv_distance_km } km, { iv_passengers } passengers| ).
ENDMETHOD.
METHOD no_passengers.
assert_split( iv_distance_km = 10 iv_passengers = 0
iv_exp_total = '0.00' iv_exp_share = '0.00' ).
ENDMETHOD.
METHOD negative_passengers.
assert_split( iv_distance_km = 5 iv_passengers = -3
iv_exp_total = '0.00' iv_exp_share = '0.00' ).
ENDMETHOD.
METHOD single_passenger.
assert_split( iv_distance_km = 0 iv_passengers = 1
iv_exp_total = '3.00' iv_exp_share = '3.00' ).
ENDMETHOD.
METHOD distance_and_detour.
assert_split( iv_distance_km = 10 iv_passengers = 3
iv_exp_total = '9.40' iv_exp_share = '3.13' ).
ENDMETHOD.
METHOD negative_distance.
assert_split( iv_distance_km = -5 iv_passengers = 2
iv_exp_total = '4.20' iv_exp_share = '2.10' ).
ENDMETHOD.
METHOD rounds_half_away.
assert_split( iv_distance_km = 2 iv_passengers = 8
iv_exp_total = '12.20' iv_exp_share = '1.53' ).
ENDMETHOD.
METHOD minimum_share.
assert_split( iv_distance_km = 0 iv_passengers = 7
iv_exp_total = '10.20' iv_exp_share = '1.50' ).
ENDMETHOD.
METHOD minimum_boundary.
assert_split( iv_distance_km = 0 iv_passengers = 6
iv_exp_total = '9.00' iv_exp_share = '1.50' ).
ENDMETHOD.
METHOD long_ride.
assert_split( iv_distance_km = 100 iv_passengers = 5
iv_exp_total = '47.80' iv_exp_share = '9.56' ).
ENDMETHOD.
METHOD two_passengers.
assert_split( iv_distance_km = 5 iv_passengers = 2
iv_exp_total = '6.20' iv_exp_share = '3.10' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,71 @@
{
"task": "G1023",
"mutants": [
{
"object": "{{P}}RIDESHARE_SPLIT",
"mutant": "line 40: + -> - (arith)",
"status": "killed",
"hidden": "6/10",
"failed_tests": [
"DISTANCE_AND_DETOUR",
"LONG_RIDE",
"ROUNDS_HALF_AWAY",
"TWO_PASSENGERS"
]
},
{
"object": "{{P}}RIDESHARE_SPLIT",
"mutant": "line 44: < -> >= (rel)",
"status": "killed",
"hidden": "0/10",
"failed_tests": [
"DISTANCE_AND_DETOUR",
"LONG_RIDE",
"MINIMUM_BOUNDARY",
"MINIMUM_SHARE",
"NEGATIVE_DISTANCE",
"NEGATIVE_PASSENGERS",
"NO_PASSENGERS",
"ROUNDS_HALF_AWAY",
"SINGLE_PASSENGER",
"TWO_PASSENGERS"
]
},
{
"object": "{{P}}RIDESHARE_SPLIT",
"mutant": "line 51: 2 -> 3 (const)",
"status": "survived",
"hidden": "10/10",
"failed_tests": []
},
{
"object": "{{P}}RIDESHARE_SPLIT",
"mutant": "line 58: > -> <= (rel)",
"status": "killed",
"hidden": "5/10",
"failed_tests": [
"DISTANCE_AND_DETOUR",
"LONG_RIDE",
"NEGATIVE_DISTANCE",
"ROUNDS_HALF_AWAY",
"TWO_PASSENGERS"
]
},
{
"object": "{{P}}RIDESHARE_SPLIT",
"mutant": "line 59: * -> / (arith)",
"status": "killed",
"hidden": "6/10",
"failed_tests": [
"DISTANCE_AND_DETOUR",
"LONG_RIDE",
"ROUNDS_HALF_AWAY",
"TWO_PASSENGERS"
]
}
],
"valid": 5,
"killed": 4,
"kill_rate": 0.8,
"ok": true
}

View File

@@ -0,0 +1,66 @@
CLASS {{p}}rideshare_split DEFINITION PUBLIC FINAL CREATE PUBLIC.
PUBLIC SECTION.
TYPES ty_distance TYPE i.
TYPES ty_amount TYPE p LENGTH 8 DECIMALS 2.
METHODS constructor.
METHODS calculate_total
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount.
METHODS calculate_share
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_share) TYPE ty_amount.
PRIVATE SECTION.
CONSTANTS:
c_base_fee TYPE ty_amount VALUE '3.00',
c_fee_per_km TYPE ty_amount VALUE '0.40',
c_detour_fee TYPE ty_amount VALUE '1.20',
c_min_share TYPE ty_amount VALUE '1.50'.
METHODS distance_fee
IMPORTING iv_distance_km TYPE ty_distance
RETURNING VALUE(rv_fee) TYPE ty_amount.
METHODS detour_fee
IMPORTING iv_passengers TYPE i
RETURNING VALUE(rv_fee) TYPE ty_amount.
ENDCLASS.
CLASS {{p}}rideshare_split IMPLEMENTATION.
METHOD constructor.
ENDMETHOD.
METHOD calculate_total.
IF iv_passengers < 1.
RETURN.
ENDIF.
rv_total = c_base_fee + distance_fee( iv_distance_km ) + detour_fee( iv_passengers ).
ENDMETHOD.
METHOD calculate_share.
IF iv_passengers < 1.
RETURN.
ENDIF.
DATA(lv_total) = calculate_total( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers ).
DATA lv_share TYPE p LENGTH 15 DECIMALS 5.
lv_share = lv_total / iv_passengers.
rv_share = round( val = lv_share dec = 2 ).
IF rv_share < c_min_share.
rv_share = c_min_share.
ENDIF.
ENDMETHOD.
METHOD distance_fee.
IF iv_distance_km > 0.
rv_fee = c_fee_per_km * iv_distance_km.
ENDIF.
ENDMETHOD.
METHOD detour_fee.
rv_fee = c_detour_fee * ( iv_passengers - 1 ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,66 @@
CLASS ltc_rideshare_split DEFINITION FINAL FOR TESTING DURATION SHORT RISK LEVEL HARMLESS.
PRIVATE SECTION.
DATA mo_cut TYPE REF TO {{p}}rideshare_split.
METHODS setup.
METHODS assert_split
IMPORTING iv_distance_km TYPE {{p}}rideshare_split=>ty_distance
iv_passengers TYPE i
iv_exp_total TYPE {{p}}rideshare_split=>ty_amount
iv_exp_share TYPE {{p}}rideshare_split=>ty_amount.
METHODS no_passengers FOR TESTING.
METHODS single_passenger FOR TESTING.
METHODS distance_and_detour FOR TESTING.
METHODS negative_distance FOR TESTING.
METHODS rounds_half_away FOR TESTING.
METHODS minimum_share FOR TESTING.
ENDCLASS.
CLASS ltc_rideshare_split IMPLEMENTATION.
METHOD setup.
mo_cut = NEW {{p}}rideshare_split( ).
ENDMETHOD.
METHOD assert_split.
cl_abap_unit_assert=>assert_equals(
exp = iv_exp_total
act = mo_cut->calculate_total( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers ) ).
cl_abap_unit_assert=>assert_equals(
exp = iv_exp_share
act = mo_cut->calculate_share( iv_distance_km = iv_distance_km
iv_passengers = iv_passengers ) ).
ENDMETHOD.
METHOD no_passengers.
assert_split( iv_distance_km = 12 iv_passengers = 0
iv_exp_total = '0.00' iv_exp_share = '0.00' ).
ENDMETHOD.
METHOD single_passenger.
assert_split( iv_distance_km = 4 iv_passengers = 1
iv_exp_total = '4.60' iv_exp_share = '4.60' ).
ENDMETHOD.
METHOD distance_and_detour.
assert_split( iv_distance_km = 10 iv_passengers = 3
iv_exp_total = '9.40' iv_exp_share = '3.13' ).
ENDMETHOD.
METHOD negative_distance.
assert_split( iv_distance_km = -2 iv_passengers = 2
iv_exp_total = '4.20' iv_exp_share = '2.10' ).
ENDMETHOD.
METHOD rounds_half_away.
assert_split( iv_distance_km = 2 iv_passengers = 8
iv_exp_total = '12.20' iv_exp_share = '1.53' ).
ENDMETHOD.
METHOD minimum_share.
assert_split( iv_distance_km = 0 iv_passengers = 7
iv_exp_total = '10.20' iv_exp_share = '1.50' ).
ENDMETHOD.
ENDCLASS.

View File

@@ -0,0 +1,59 @@
# 1. Goal
A ride-sharing service splits the cost of a shared ride between the passengers.
The booking program calls the calculation after each completed ride. The program
needs the total cost of the ride and the share of each passenger.
# 2. Open questions
None.
# 3. Context
- A ride has one driver and one or more passengers. The driver is not a
passenger and pays nothing.
- The service charges a base fee, a distance fee and a detour fee.
- The booking program knows the distance of the ride in whole kilometres and
the number of passengers of the ride.
# 4. Contract
- Create the class {{P}}RIDESHARE_SPLIT in package $TMP.
- The class is public and final. It has a public constructor without parameters.
- The class has these public types:
- TY_DISTANCE: a whole number of kilometres.
- TY_AMOUNT: a packed number with 2 decimals. The currency is euro.
- The class has these public methods. Do not add other public methods.
- CALCULATE_TOTAL
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_total) TYPE ty_amount
- CALCULATE_SHARE
IMPORTING iv_distance_km TYPE ty_distance
iv_passengers TYPE i
RETURNING VALUE(rv_share) TYPE ty_amount
# 5. Business rules
Apply the rules in this sequence.
1. The number of passengers is the number of persons who share the ride.
2. If the number of passengers is less than 1, the total cost is 0.00 and the
share is 0.00. Rules 3 to 7 do not apply.
3. A distance below 0 counts as 0 kilometres.
4. The total cost of the ride is the sum of:
- a base fee of 3.00,
- a distance fee of 0.40 for each kilometre,
- a detour fee of 1.20 for each passenger after the first passenger.
5. The share of a passenger is the total cost divided by the number of
passengers.
6. Round the share to 2 decimals. Round a half away from zero (for example,
2.345 becomes 2.35).
7. The minimum share is 1.50. If the rounded share is below 1.50, the share is
1.50. The minimum share does not change the total cost.
# 6. Constraints
- Release target: 8.16 (SAP_BASIS 816).
- Coding standards: Clean ABAP. Methods below 40 statements. No global
variables. No comment that restates the code.
- Out of scope: no database table, no CDS view, no report, no function module,
no interface.
# 7. Acceptance
- The class is active and has no syntax error.
- The hidden tests pass.
- Write your own ABAP Unit tests for the class.

View File

@@ -0,0 +1,47 @@
{
"id": "G1023",
"category": "A",
"object_type": "CLAS",
"difficulty": 2,
"release_target": "v816",
"expected_outcome": "implement",
"budget": {
"max_tool_calls": 60,
"max_activations": 15
},
"seed": [],
"contract": [
{
"type": "CLAS",
"name": "{{P}}RIDESHARE_SPLIT"
}
],
"out_of_scope": [
"database tables",
"CDS views",
"reports",
"function modules",
"interfaces"
],
"hidden_tests": [
{
"type": "CLAS",
"name": "{{P}}T21_HIDDEN",
"file": "hidden/t21_hidden.clas.abap",
"description": "T21 hidden tests for the ride-sharing cost split"
}
],
"reference": [
{
"type": "CLAS",
"name": "{{P}}RIDESHARE_SPLIT",
"file": "reference/rideshare_split.clas.abap",
"description": "Ride-sharing cost split calculator",
"testclasses_file": "reference/rideshare_split.testclasses.abap"
}
],
"craft_checks": [
"method_length",
"no_global_variables"
]
}