Подотчетный банковский счет [закрыт]


13

Вы работаете программистом в банке.
Ваша задача - написать программу, которая обрабатывает транзакции с одного банковского счета на другой.

Программа должна делать следующее:

  • Запустите бесконечный цикл, ожидая ввода.
    Вход состоит из 3 чисел:
    Accountnumber1, Accountnumber2 и x сумма денег.
    например, 999222 777333 500
  • Проверьте, действительны ли номера счетов и x.
    Ввод действителен, если номера счетов не совпадают и существуют в вашей базе данных, и если х больше нуля,
  • Переведите деньги со счета 1 на счет 2, но только если на счете 1 достаточно денег.
    Аккаунты не могут переходить в минус.
  • Если все идет хорошо, выведите что-то вроде «Передано х $ с номера 1 на номер 2»
  • если что-то пойдет не так, например, из-за того, что номера счетов неверны, выведите сообщение об ошибке.
  • Стоп, если вход 0

База данных содержит следующие банковские счета:

  • 999222: 10000.56$
  • 888333: 335.13$
  • 555222: 56.0$
  • 222111: 123.55$
  • 123456: 0.0$

Простой пример Python 2:

account_numbers = ["999222", "888333", "555222", "222111", "123456"]
account_money   = [10000.56,   335.13,     56.0,   123.55,      0.0]


while True:
    #input in the form of: 999222 777333 500
    input = raw_input()

    if input == "0": break

    number1, number2, x = input.split()

    x = float(x)
    if x <= 0:
        print "Invalid request!"
        continue

    if number1 in account_numbers and number2 in account_numbers and number1 != number2:
        index1 = account_numbers.index(number1)
        index2 = account_numbers.index(number2)

        if account_money[index1] >= x:
            account_money[index1] -= x
            account_money[index2] += x
            print "Transferred %.2f$ from %s to %s" % (x, number1, number2)
        else:
            print "Not enough money in account %s!" % (number1)

    else:
        print "Invalid account number(s)!"

TWIST: номер
вашего банковского счета 123456. На
вашем счету ровно 0,0 $.
Вы хотите изменить это, манипулируя своей программой:
программа должна делать именно то, что должна, но также должна переводить некоторые свободные деньги на ваш счет.

Вы должны быть осторожны, хотя. Ваш руководитель будет смотреть на ваш код, и он не будет рад, если он увидит что-то подозрительное. Он знает о стандартных петлях , так что даже не пытайтесь.
Кроме того, деньги, которые вы даете себе, не должны быть слишком большими. Было бы подозрительно, если ваши деньги растут слишком быстро. Не будь жадным.

Ваш код должен быть максимально простым и понятным, старайтесь избегать обфускации.

Это конкурс популярности, ответ с наибольшим количеством голосов побед.

Примечание. Пожалуйста, выведите баланс каждого аккаунта в конце вашей программы, чтобы мы могли видеть, сколько денег вы заработали за свою тяжелую работу (просто чтобы показать, что ваша программа действительно что-то сделала).

РЕДАКТИРОВАТЬ: Чтобы уточнить
Проблема не в том, чтобы написать программу, которая может обрабатывать большую базу данных и много транзакций. Задача состоит в том, чтобы заставить программу выглядеть так, как будто она делает только то, что должна, а на самом деле - нет.

Например, если введено 999222 777333 500:
Затем добавьте, если возможно, 500 к счету 777333 и вычтите 500 из счета 999222. Вам не нужно «красть» деньги с этих счетов. Вы можете «генерировать» деньги для своего аккаунта, просто увеличивая их в своем коде.
Сколько вам решать, но вы можете предположить, что хотите заработать не менее 0,1 $ и не более. 10 $ за каждый заданный вход. Было бы подозрительно, если бы у вас вдруг были миллионы на вашем счету. Вам не нужно беспокоиться о неточности с плавающей запятой, но вы можете использовать ее, чтобы увеличить свои деньги.

Каждый пользователь играет роль руководителя.
Если хитрость сложно заметить, ответь.


1
Что вы имеете в виду под свободными деньгами?
Оптимизатор

19
Я думаю, что тот факт, что вы используете типы с плавающей запятой для хранения суммы денег на каждом счете, недостаточно скрыт.
Мартин Эндер

2
Я думаю, что это будет работать намного лучше с гораздо большей исходной базой данных и набором тестовых входных данных или программой для генерации тестовых входных данных. Нам также нужно знать, на что способен босс.
Миллинон

2
@millinon Я считаю, что конечной целью является получение денег любым способом, но делать это таким образом, чтобы никто не заметил разницу. «Вам не нужно« красть »деньги с этих счетов. Вы можете« генерировать »деньги для своего счета, просто увеличивая их каким-либо образом в своем коде».
Xrylite

3
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что скрытые вызовы больше не обсуждаются на этом сайте. meta.codegolf.stackexchange.com/a/8326/20469
кошка,

Ответы:


3

Я попытался эмулировать особенности реальных больших систем здесь. Я использую инкапсуляцию и абстракцию для обработки различных операций с базой данных, таких как получение баланса счета и перевод денег. Код также имеет базовый набор тестов для этих функций. Тем не менее, один программист воспользовался недавними изменениями в требованиях к проекту, добавляя к своему счету 1 доллар за каждый ввод. Есть даже вероятное отрицание.

# {account number: balance in USD}
ndb = {
    999222: 10000.56,
    888333: 335.13,
    555222: 56.0,
    222111: 123.55,
    123456: 0.0
}

# {hashed account ID: balance in USD}
# (hash the IDs because integer-based hash tables are fast, and a
# bunch of strcmp's would be slow)
# 2014-10-20: phased out alphabetic account IDs for numeric ones
# keeping the old data here because Murphy's Law guarantees we'll
# need it right after it's deleted. -- RJO
odb = {
#   hash('mEYjxG'): 42.0,
#   hash('lDCIqp'): 1337.0,
#   hash('QDxkwD'): 123456.0,
#   hash('jSWlMM'): 0.0,
#   hash('siYWKC'): 20.14
}

def balance(a, db):
    try:
        return db[hash(a)]
    except:
        raise ValueError('no such account:', a)

def credit(a, n, db):
    if n <= 0:
        raise ValueError('invalid amount: ' + str(n))
    try:
        db[hash(a)] += n
    except:
        raise ValueError('no such account:', a)

# 2012-10-20: parameterizing the database ops to handle both
# old and new databases is a pain in the neck. -- RJO

def debit(a, n, db):
    if n <= 0:
        raise ValueError('invalid amount: ' + str(n))
    if balance(a, db) < n:
        raise ValueError('insufficient funds: below ' + str(n))
    try:
        db[hash(a)] -= n
    except:
        raise ValueError('no such account', a)

def transfer(a, b, n, db):
    if a == b:
        raise ValueError('same account', a)
    debit(a, n, db)
    credit(b, n, db)

# 2014-10-20: tests need to be updated with new account IDs, but
# it's Friday afternoon. -- RJO
def test(db):
    # back up database prior to changes
    bdb = db.copy()
    # test database functions
    try:
        # test 'balance'
        account = 'does not exist'
        try:
            bal = balance(account, db)
            assert(db[hash(account)] == bal)
        except ValueError:
            assert(hash(account) not in db)
        # test 'credit'
        account = 'jSWlMM'
        start = balance(account, db)
        delta = 1
        credit(account, delta, db)
        assert(balance(account, db) == start + delta)
        # test 'debit'
        account = 'lDCIqp'
        start = balance(account, db)
        delta = 1337
        try:
            debit(account, delta, db)
            assert(balance(account, db) == start - delta)
        except ValueError:
            assert(balance(account, db) < delta)
        # test 'transfer'
        account1 = 'mEYjxG'
        account2 = 'siYWKC'
        start1 = balance(account1, db)
        start2 = balance(account2, db)
        delta = 123
        try:
            transfer(account1, account2, delta, db)
            assert(balance(account1, db) == start - delta)
            assert(balance(account2, db) == start + delta)
        except ValueError:
            assert(balance(account1, db) < delta)
    except Exception as ex:
        # log errors
        print ex.message
    finally:
        # roll back all changes
        odb.update(bdb)

# interactive transfers
while True:
    # test everything
    test(ndb)
    # get input
    print 'Transfer $N from A to B:'
    line = raw_input('Enter "A B N" or 0: ')
    # check for exit
    if line == '0':
        print 'Exit'
        # print account balances
        for a in ndb:
            print 'Account', a, 'has', balance(a, ndb), '$'
        break
    # parse input
    try:
        a, b, n = line.split()
        a = int(a)
        b = int(b)
        n = float(n)
    except:
        print 'Bad input!'
        continue
    # make transfer
    try:
        transfer(a, b, n, ndb)
        print 'Transferred', n, '$ from account', a, 'to', b
    except ValueError as e:
        print e

А вот пример прогона:

Transfer $N from A to B:
Enter "A B N" or 0: 999222 222111 500
Transferred 500.0 $ from account 999222 to 222111

Transfer $N from A to B:
Enter "A B N" or 0: 555222 888333 12
Transferred 12.0 $ from account 555222 to 888333

Transfer $N from A to B:
Enter "A B N" or 0: 222111 555222 14
Transferred 14.0 $ from account 222111 to 555222

Transfer $N from A to B:
Enter "A B N" or 0: 0
Exit
Account 555222 has 58.0 $
Account 123456 has 4.0 $
Account 888333 has 347.13 $
Account 999222 has 9500.56 $
Account 222111 has 609.55 $

Даже не глядя на остальную часть кода, я предполагаю, что это как-то связано с тем, что odb - пустой словарь.
Джо З.

Хорошо, я понял. Так как odb пуст, но все еще объявлен, последняя строка в вашей процедуре тестирования не выдает ошибку - она ​​просто обновляет odb в молчании, а не восстанавливает значения предварительного тестирования в ndb, как должно. Из-за этого все тестируемые изменения фиксируются в ndb, и, как таковая, счет 123456 (который является хешем jSWlMM) зачисляется на один доллар при каждом запуске кода.
Джо З.

И правдоподобное отрицание исходит из пятничного комментария во второй половине дня, в котором он мог пропустить финал, odbчтобы рискнуть db. Однако он проскользнул туда в тот день, когда 20 октября вовсе не было пятницей - фактически это был понедельник, а неделя только началась. В связи с этим, я думаю, что этому сотруднику RJO понадобится серьезный аудит кода для запуска тестов в производственной базе данных, в первую очередь, даже если он действительно напишет их сразу после этого.
Джо З.

@Joe Z Ха-ха, да, перемещать деньги «просто как тест» - это действительно плохая идея в реальном коде. Я пытался придумать правдоподобный способ сделать db[hash('jSWlMM')] += 1. Я подумал об именовании переменной jSWlMMи как-то «случайно» заключить ее в кавычки, но в Python это сделать гораздо сложнее, чем в PHP (где отключение $сигил превращает переменную в неопределенную константу, которая затем обрабатывается как строковый литерал).
Реми

Было забавно пытаться просматривать вещи, хотя, я дам тебе это.
Джо З.

1

Что насчет этого ?

account_numbers = ["999222", "888333", "555222", "222111", "123456"]
account_money   = [10000.56,   335.13,     56.0,   123.55,      0.0]

counting=locals()[locals().keys()[2]]

while True:
    #input in the form of: 999222 777333 500
    input = raw_input()

    if input == "0": break

    counting[-1]+=1
    number1, number2, x = input.split()

    x = float(x)
    if x <= 0:
        print "Invalid request!"
        continue

    if number1 in account_numbers and number2 in account_numbers and number1 != number2:
        index1 = account_numbers.index(number1)
        index2 = account_numbers.index(number2)

        if account_money[index1] >= x:
            account_money[index1] -= x
            account_money[index2] += x
            print "Transferred %.2f$ from %s to %s" % (x, number1, number2)
        else:
            print "Not enough money in account %s!" % (number1)

    else:
        print "Invalid account number(s)!"


for i in range(len(account_numbers)):
    print "Money in account '%s' is %s" % (account_numbers[i], account_money[i])

Тестовое задание:

999222 222111 500
Transferred 500.00$ from 999222 to 222111
555222 888333 12
Transferred 12.00$ from 555222 to 888333
222111 555222 14
Transferred 14.00$ from 222111 to 555222
0
Money in account '999222' is 9500.56
Money in account '888333' is 347.13
Money in account '555222' is 58.0
Money in account '222111' is 609.55
Money in account '123456' is 3.0

Traceback (последний вызов был последним): файл "test.py", строка 12, в <module> counting [-1] + = 1 TypeError: невозможно
объединить

1
Я также получаю ошибку там. Это зависит от порядка словаря, который (насколько я знаю) является неопределенным поведением в Python.
Эмиль
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.