Rekening Bank Tertutup [ditutup]

13

Anda bekerja sebagai programmer untuk sebuah bank.
Tugas Anda adalah menulis program yang menangani transaksi dari satu rekening bank ke yang lain.

Program harus melakukan hal berikut:

  • Jalankan dalam loop tak terbatas menunggu input.
    Input terdiri dari 3 angka:
    Accountnumber1, Accountnumber2 dan x jumlah uang.
    misalnya 999222 777333 500
  • Periksa apakah nomor akun dan x valid.
    Masukan ini valid jika nomor akun tidak sama dan ada di database Anda dan jika x lebih besar dari nol,
  • Transfer uang dari akun1 ke akun2, tetapi hanya jika akun1 memiliki cukup uang.
    Akun tidak boleh masuk ke negatif.
  • Jika semuanya berjalan dengan baik, cetak sesuatu seperti "Transfer x $ dari number1 ke number2"
  • jika terjadi kesalahan, misalnya karena nomor akun tidak valid, cetak pesan kesalahan.
  • Berhenti jika inputnya 0

Basis data berisi rekening bank berikut:

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

Contoh Python 2 sederhana:

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:
Nomor rekening bank Anda adalah 123456.
Anda memiliki tepat 0,0 $ di akun Anda.
Anda ingin mengubahnya dengan memanipulasi program Anda:
Program harus melakukan persis apa yang seharusnya dilakukan, tetapi juga harus mentransfer sejumlah uang gratis ke akun Anda.

Anda harus berhati-hati. Atasan Anda akan melihat kode Anda dan dia tidak akan senang jika dia melihat sesuatu yang mencurigakan. Dia tahu tentang Lubang Lingkaran Standar , jadi jangan coba-coba.
Juga, uang yang Anda berikan kepada diri sendiri tidak boleh terlalu banyak. Akan mencurigakan jika uang Anda bertambah terlalu cepat. Jangan serakah.

Kode Anda harus sesederhana dan sejelas mungkin, cobalah untuk menghindari kebingungan berat.

Ini adalah kontes popularitas, jawabannya dengan kemenangan terbanyak.

Catatan: Tolong cetak saldo setiap akun di akhir program Anda, sehingga kami dapat melihat berapa banyak uang yang Anda hasilkan dari kerja keras Anda (hanya untuk menunjukkan bahwa program Anda benar-benar melakukan sesuatu).

EDIT: Untuk memperjelas
Tantangannya adalah bukan untuk menulis sebuah program yang dapat menangani database besar dan banyak transaksi. Tantangannya adalah untuk membuat program terlihat seperti hanya melakukan apa yang seharusnya dilakukan, tetapi kenyataannya tidak.

Sebagai contoh jika inputnya adalah 999222 777333 500:
Kemudian tambahkan, jika mungkin, 500 ke akun 777333 dan kurangi 500 dari akun 999222. Anda tidak perlu "mencuri" uang dari akun itu. Anda dapat "menghasilkan" uang untuk akun Anda dengan hanya menambahnya entah bagaimana dalam kode Anda.
Berapa terserah Anda, tetapi Anda dapat berasumsi bahwa Anda ingin mendapatkan setidaknya $ 0,1 dan maks. 10 $ untuk setiap input yang diberikan. Akan mencurigakan jika Anda tiba-tiba memiliki jutaan di akun Anda. Anda tidak perlu khawatir tentang ketidaktepatan floating point, tetapi Anda dapat menggunakannya untuk menambah uang Anda.

Setiap pengguna memainkan peran sebagai penyelia.
Jika triknya sulit dikenali jawabannya.

Markuz
sumber
1
Apa yang Anda maksud dengan uang gratis?
Pengoptimal
19
Saya pikir fakta bahwa Anda menggunakan tipe floating-point untuk menyimpan jumlah uang di setiap akun cukup curang.
Martin Ender
2
Saya pikir ini akan bekerja jauh lebih baik dengan basis data awal yang jauh lebih besar dan baik satu set input contoh atau program untuk menghasilkan input tes. Kita juga perlu tahu apa yang mampu dideteksi bos.
milinon
2
@ Millinon Saya percaya tujuan utamanya adalah untuk mendapatkan uang melalui metode apa pun, tetapi untuk melakukannya sedemikian rupa sehingga tidak ada yang memperhatikan perbedaannya. "Anda tidak perlu" mencuri "uang dari akun-akun itu. Anda dapat" menghasilkan "uang untuk akun Anda dengan hanya menambahnya entah bagaimana dalam kode Anda."
Xrylite
3
Saya memberikan suara untuk menutup pertanyaan ini sebagai di luar topik karena tantangan curang tidak lagi pada topik di situs ini. meta.codegolf.stackexchange.com/a/8326/20469
cat

Jawaban:

3

Saya sudah mencoba meniru fitur sistem besar dunia nyata di sini. Saya menggunakan enkapsulasi dan abstraksi untuk menangani berbagai operasi ke database, seperti mendapatkan saldo akun dan mentransfer uang. Kode ini juga memiliki test suite dasar untuk fungsi-fungsi tersebut. Namun, satu programmer telah mengambil keuntungan dari perubahan terbaru dalam persyaratan proyek untuk menambahkan $ 1 ke akun mereka dengan setiap input. Bahkan ada penyangkalan yang masuk akal.

# {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

Dan inilah contoh dijalankan:

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 $
Remy
sumber
Tanpa melihat sisa kode saya kira itu ada hubungannya dengan ODB menjadi kamus kosong.
Joe Z.
Oke, saya mengerti. Karena odb kosong tetapi masih dideklarasikan, baris terakhir dalam prosedur pengujian Anda tidak menimbulkan kesalahan - ini hanya memperbarui odb secara diam-diam alih-alih mengembalikan nilai pra-pengujian ke ndb seperti yang seharusnya. Karena itu, semua perubahan pengujian dikomit ke ndb, dan karenanya, akun 123456 (yang merupakan hash of jSWlMM) dikreditkan satu dolar setiap kali kode dijalankan.
Joe Z.
Dan penyangkalan yang masuk akal datang dari komentar Jumat sore di mana dia bisa melewatkan final odbuntuk kesempatan itu db. Namun, ia menyelinap di sana pada tanggal 20 Oktober itu bukan hari Jumat sama sekali - pada kenyataannya, hari Senin dan minggu baru saja dimulai. Dalam hal ini, saya pikir orang RJO ini akan memerlukan audit kode serius untuk menjalankan tes pada basis data produksi, bahkan jika dia memang menulisnya kembali setelah itu.
Joe Z.
@ Jo Z Haha, ya, menggerakkan uang "hanya sebagai ujian" adalah ide yang sangat buruk dalam kode nyata. Saya sedang berusaha menemukan cara yang masuk akal untuk dilakukan db[hash('jSWlMM')] += 1. Saya mempertimbangkan memberi nama variabel jSWlMMdan "tidak sengaja" mengutipnya, tapi itu jauh lebih sulit dilakukan dengan Python daripada PHP (di mana meninggalkan $sigil mengubah variabel menjadi konstanta yang tidak terdefinisi, yang kemudian diperlakukan sebagai string literal).
Remy
Sangat menyenangkan mencoba melihat-lihat hal-hal, saya akan memberikan Anda
Joe Z.
1

Bagaimana dengan ini ?

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])

Uji:

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
Alain Tésio
sumber
Traceback (panggilan terakhir terakhir): File "test.py", baris 12, dalam <module> menghitung [-1] + = 1 TypeError: tidak dapat menggabungkan objek 'str' dan 'int'
ErlVolton
1
Saya juga mendapatkan kesalahan di sana. Ini bergantung pada pemesanan kamus, yang (sejauh yang saya tahu) perilaku tidak terdefinisi dalam Python.
Emil