언더 핸드 은행 계좌 [폐쇄]


13

은행의 프로그래머로 일하고 있습니다.
당신의 임무는 한 은행 계좌에서 다른 은행 계좌로의 거래를 처리하는 프로그램을 작성하는 것입니다.

프로그램은 다음을 수행해야합니다.

  • 입력을 기다리는 무한 루프에서 실행하십시오.
    입력은 3 개의 숫자 :
    Accountnumber1, Accountnumber2 및 x 금액입니다.
    예 : 999222 777333 500
  • 계좌 번호와 x가 유효한지 확인하십시오.
    계정 번호가 동일하지 않고 데이터베이스에 존재하고 x가 0보다 크면 입력이 유효합니다.
  • account1에서 account2로 돈을 이체하십시오. 그러나 account1에 충분한 돈이있는 경우에만 가능합니다.
    계정은 부정으로 들어갈 수 없습니다.
  • 모든 것이 잘된다면 "number1에서 number2로 x $ 전송"과 같은 것을 인쇄하십시오.
  • 계정 번호가 잘못되어 문제가 발생하면 오류 메시지를 인쇄하십시오.
  • 입력이 0이면 정지

데이터베이스에는 다음 은행 계좌가 포함됩니다.

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

간단한 파이썬 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:
가능하면 계정 777333에 500을 추가하고 계정 999222에서 500을 뺍니다. 해당 계정에서 돈을 "훔칠"필요는 없습니다. 코드에서 어떻게 든 돈을 늘리면 계정에서 돈을 "생성"할 수 있습니다.
귀하에게 얼마의 비용이 들지만 최소한 0.1 $ 이상을 벌고 싶다고 가정 할 수 있습니다. 주어진 각 입력에 대해 10 $. 계정에 갑자기 수백만의 사용자가 있으면 의심 할 것입니다. 부동 소수점 부정확도에 대해 걱정할 필요는 없지만 돈을 늘리기 위해 사용할 수 있습니다.

모든 사용자는 감독자의 역할을합니다.
트릭이 답을 찾기 어려울 경우 대답.


1
공짜 돈이란 무엇입니까?
Optimizer

19
각 계정에 금액을 저장하기 위해 부동 소수점 유형을 사용하고 있다는 사실이 충분하다고 생각합니다.
Martin Ender

2
나는 이것이 훨씬 큰 초기 데이터베이스와 예제 테스트 입력 세트 또는 테스트 입력을 생성하는 프로그램에서 훨씬 잘 작동한다고 생각합니다. 또한 보스가 무엇을 감지 할 수 있는지 알아야합니다.
millinon

2
@ millinon 나는 궁극적 인 목표는 어떤 방법을 통해 돈을 얻는 것이지만 아무도 그 차이를 알지 못하는 방식으로 돈을 얻는 것이라고 생각합니다. "그 계좌에서 돈을"도둑질 "할 필요는 없습니다. 코드에서 어떻게 든 돈을 늘리면 계좌에서 돈을"생성 "할 수 있습니다."
Xrylite

3
나는이 문제를 주제로 다루지 않기로 결심했다. 왜냐하면이 사이트에서 미숙 한 도전은 더 이상 주제가 아니기 때문이다. meta.codegolf.stackexchange.com/a/8326/20469
cat

답변:


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가 빈 사전 인 것과 관련이 있다고 생각합니다.
Joe Z.

알았어 odb는 비어 있지만 여전히 선언되었으므로 테스트 절차의 마지막 줄은 오류를 발생시키지 않습니다. 사전 테스트 값을 ndb로 복원하는 대신 odb를 자동으로 업데이트하기 만하면됩니다. 이로 인해 모든 테스트 변경 사항이 ndb에 커밋되므로 계정 123456 (의 해시 jSWlMM)은 코드가 실행될 때마다 1 달러의 크레딧을받습니다.
Joe Z.

그리고 그럴듯한 부인은 금요일 오후의 논평에서 비롯된 odb것이다 db. 그러나 10 월 20 일은 금요일이 아니었다. 실제로 월요일이었고 주가 막 시작되었다. 그 문제 때문에,이 RJO 동료는 처음부터 프로덕션 데이터베이스에서 테스트를 다시 실행하더라도 테스트를 실행하려면 심각한 코드 감사가 필요하다고 생각합니다.
Joe Z.

@Joe Z Haha, 그렇습니다. "테스트처럼"돈을 옮기는 것은 실제 코드에서 정말 나쁜 생각입니다. 나는 그럴듯한 방법을 찾으려고 노력했다 db[hash('jSWlMM')] += 1. 나는 변수의 이름을 jSWlMM정하고 실수로 인용 하는 것을 고려 했지만, 파이썬에서는 파이썬보다 수행하기가 훨씬 어렵습니다 ( $시길을 벗어나 면 변수가 정의되지 않은 상수로 바뀌고 문자열 리터럴로 처리됩니다).
레미

그래도 사물을 살펴 보는 것은 재미있었습니다.
Joe Z.

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

역 추적 (가장 최근의 콜 최종) : 파일 "test.py"라인 (12)에서 <모듈> 계수 [-1] + = 1 오류 : 합칠 수없는 'STR'과 '내부'객체
ErlVolton

1
또한 오류가 발생합니다. 이것은 파이썬에서 정의되지 않은 동작 인 사전의 순서에 의존합니다.
Emil
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.