0

CUSTOMER class

class
    CUSTOMER
create
    make

feature{NONE} -- Creation

make(a_name:STRING)
        -- Create a customer with an `account'
    local
        l_account: ACCOUNT
        l_name: IMMUTABLE_STRING_8
        l_bank: BANK
    do
        l_name := a_name
        name := l_name
        create l_account.make_with_name (a_name)
        create l_bank.make
        b := l_bank
        account := l_account
    ensure
        correct_name: name ~ a_name
        correct_balance: balance = balance.zero
    end

feature -- queries

name: IMMUTABLE_STRING_8

balance: VALUE
    do
        Result := account.balance
    end

account: ACCOUNT

b: BANK




 invariant
    name_consistency: name ~ account.name
    balance_consistency: balance = account.balance
 end

part of BANK class:

   make  -- make a bank

       do
          count := 0
          create [ARRAY_LIST][CUSTOMER] customers.make(10)
          customers.count.set_Item(10)

       end

   new(name1: STRING) -- add a new customer to bank

       require 
         ....
       local
            c: CUSTOMER
       do
          create c.make(name1)
          customers.extend(c)
          count := count + 1




       ensure
          ...
       end

I get a check assertion error from ARRAY_LIST class when trying to put a customer in the array. The tag i get is "valid_index" I don't know why its wrong because the index is right and I set the count for the array and give the correct index.

customers is of type CUSTOMER class

bank has customers and customers have accounts

CUSTOMER has an ACCOUNT class

geforce
  • 61
  • 6

2 Answers2

1

If you look at feature `count', you will see it is a function, not an attribute. It returns the count of the SPECIAL. You then edit this result. But if you look at {SPECIAL}.count, it is a built-in external routine, not an attribute. So it is probably not effected by you call. (You can test valid_index prior to calling put_i_th to verify this).

Fundamentaly, ARRAYED_LIST is a LIST, not an ARRAY (it is an ARRAY, but that is an implementation detail). So your algorithm is invalid for a list (you can only add new items on to the end of the list with extend, or to the front with put_front. The latter is inefficient on an ARRAYED_LIST.)

1

There are a few issues with the presented code.

  1. Creation instruction

    create {ARRAYED_LIST [CUSTOMER]} customers.make (10)
    

    allocates enough space to store 10 elements. It also sets customers.count to 0, the current number of elements in the list. There is no need to track this number yourself using your own count. The code also suggests that the attribute customers is declared to be of type ARRAYED_LIST [CUSTOMER]. In that case there is no reason to repeat the type in the creation instruction. It can be simplified to

    create customers.make (10)
    
  2. customers.count is updated automatically when new elements are added to the list. It should not be changed by hand. (And it cannot be changed as explained in the other answer.) Just to see why you get a precondition violation you can check the value of customers.count just before calling customers.put_i_th (in the debugger or by printing the value to the console). No elements have been added at this point yet, so it is 0.

  3. Because ARRAYED_LIST is an implementation of LIST, items should be added/removed using the interface of LIST (it is helpful to have a look at the features of this class, including inherited ones). customers.put_i_th can be used to replace existing elements only (as its precondition valid_index suggests and the feature comment confirms: -- Replace i-th entry, if in index interval, by v.). The particular one that adds a new element to the end of the list is extend, so the corresponding line looks like

    customers.extend (c)
    

A general advice would be to pay attention to feature preconditions and feature comments and to look at class interfaces (there is the corresponding view if you are using an Eiffel IDE). It may take some time, but it pays off in the end. You may also find the section about naming conventions in Style Guidelines useful.

Alexander Kogtenkov
  • 5,770
  • 1
  • 27
  • 35
  • Thanks for the help however it did not work too well. When putting the statement "create customers.make(10)" i got a compiler error saying the class I'm referencing is deferred. Also when switching to extend I still got a check assertion violation error. I will be making another post but this time I will show the whole CUSTOMER class to see maybe why it is causing me problems – geforce Jan 15 '16 at 15:00
  • 1
    @GeForce: It means that `customers` is of type `LIST [CUSTOMER]` (that is deferred) or similar. In that case the explicit type specification in the creation instruction is required. As to the assertion violation for `extend` - is it really related to it? It would be strange because it has only one precondition `extendible` that is always `True` for `ARRAYED_LIST`. – Alexander Kogtenkov Jan 15 '16 at 15:36
  • I edited the post with the CUSTOMER class. I added bank reference in CUSTOMER and initialized it and some of the check violations went away but there are still some check assertion violations there. I think the errors might be coming from CUSTOMER class because I have not properly defined features or attributes. There are still some post-condition violations and check assertions but not every test case anymore just 1 or 2. Do you see anything else I'm not adding to the CUSTOMER class? – geforce Jan 15 '16 at 17:39
  • @GeForce: If `name` has the same type in `CUSTOMER` and `ACCOUNT` I do not immediately see a problem. But as soon as you get an assertion violation you can check an exception trace or use a debugger to figure out what exactly went wrong. – Alexander Kogtenkov Jan 16 '16 at 11:38