Elde Tutulan Banka Hesabı [kapalı]


13

Bir banka için programcı olarak çalışıyorsunuz.
Göreviniz bir banka hesabından diğerine işlemleri gerçekleştiren bir program yazmaktır.

Program aşağıdakileri yapmalıdır:

  • Sonsuz bir döngüde girişi bekle.
    Giriş 3 sayıdan oluşur: Hesap numarası1, Hesap numarası2
    ve x para miktarı.
    örneğin, 999222 777333 500
  • Hesap numaralarının ve x'in geçerli olup olmadığını kontrol edin.
    Hesap numaraları aynı değilse ve veritabanınızda mevcutsa ve x sıfırdan büyükse giriş geçerlidir,
  • Parayı account1'den account2'ye aktarın, ancak yalnızca account1'in yeterli parası varsa.
    Hesapların negatif hesaplara girmesine izin verilmez.
  • Her şey yolunda giderse, "Aktarılan x $ sayı1'den sayı2'ye" gibi bir şey yazdırın
  • bir şeyler ters giderse, örneğin hesap numaraları geçersiz olduğu için bir hata mesajı yazdırın.
  • Giriş 0 ise dur

Veritabanı aşağıdaki banka hesaplarını içerir:

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

Basit Python 2 örneği:

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:
Banka hesap numaranız 123456. Hesabınızda
tam olarak 0.0 $ var.
Bunu programınızı manipüle ederek değiştirmek istersiniz:
Program tam olarak yapması gerekeni yapmalı, ancak hesabınıza bir miktar ücretsiz para aktarmalıdır.

Yine de dikkatli olmalısın. Amiriniz kodunuza bakar ve şüpheli bir şey görürse memnun olmaz. Standart Döngü Deliklerini biliyor , bu yüzden denemeyin bile.
Ayrıca, kendinize verdiğiniz para çok fazla olmamalıdır. Paranız çok hızlı artarsa ​​şüpheli olur. Açgözlü olma.

Kodunuz olabildiğince basit ve anlaşılır olmalı, ağır gizlenmeyi önlemeye çalışın.

Bu bir popülerlik yarışması, en çok oy alan cevap kazanıyor.

Not: Sıkı çalışmanızla ne kadar para kazandığınızı görebilmemiz için lütfen her bir hesabın bakiyesini programınızın sonunda alın (sadece programınızın gerçekten bir şey yaptığını göstermek için).

DÜZENLEME: Açıklığa kavuşturmak için Zorluk
, büyük bir veritabanı ve birçok işlem gerçekleştirebilecek bir program yazmak değil. Zor olan program, sadece yapması gereken şeyi yapıyormuş gibi görünmesini sağlamaktır, fakat gerçekte yapmaz.

Örneğin giriş şuysa 999222 777333 500:
O zaman mümkünse 777333 hesabına 500 ekleyin ve 999222 hesabından 500 çıkarın. Bu hesaplardan parayı "çalmanız" gerekmez. Hesabınız için parayı, kodunuzda bir şekilde artırarak "oluşturabilirsiniz".
Ne kadar size bağlı, ancak en az 0.1 $ ve maksimum kazanmak istediğinizi varsayabilirsiniz. Verilen her giriş için 10 $. Hesabınızda aniden milyonlarca kişinin olması şüpheli olacaktır. Kayan nokta belirsizliği konusunda endişelenmenize gerek yoktur, ancak paranızı artırmak için kullanabilirsiniz.

Her kullanıcı süpervizörün rolünü oynar.
Hile tespit etmek zor ise cevabı oylayın.


1
Bedava para ile ne demek istiyorsun?
Optimize Edici

19
Her hesaptaki para miktarını saklamak için kayan nokta türlerini kullandığınız gerçeğinin yeterince yetersiz olduğunu düşünüyorum.
Martin Ender

2
Bu çok daha büyük bir başlangıç ​​veritabanı ve bir dizi örnek test girişi veya test girişleri oluşturmak için bir program ile çok daha iyi çalışacağını düşünüyorum. Ayrıca patronun neyi tespit edebildiğini de bilmeliyiz.
millinon

2
@millinon Nihai amacın herhangi bir yöntemle para kazanmak olduğuna inanıyorum, ancak bunu farkı kimse fark etmeyecek şekilde yapmak. "Bu hesaplardan parayı" çalmak "zorunda değilsiniz. Hesabınızda paranızı, kodunuzda bir şekilde artırarak" oluşturabilirsiniz ".
Xrylite

3
Bu soruyu konu dışı olarak kapatmak için oy kullanıyorum çünkü el altında kalan zorluklar artık bu sitede konuyla ilgili değil. meta.codegolf.stackexchange.com/a/8326/20469
kedi

Yanıtlar:


3

Burada gerçek dünyadaki büyük sistemlerin özelliklerini taklit etmeye çalıştım. Bir hesap bakiyesi almak ve para transferi gibi farklı işlemleri veritabanına işlemek için kapsülleme ve soyutlama kullanıyorum. Kod ayrıca bu işlevler için temel bir test paketine sahiptir. Bununla birlikte, bir programcı, her girdiyle hesaplarına 1 $ eklemek için proje gereksinimlerindeki son değişikliklerden yararlanmıştır. Hatta makul bir inkar edilebilirlik var.

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

Ve işte örnek bir çalışma:

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 $

Hatta kodun geri kalanına bakmadan ben boş bir sözlük olmak odb ile ilgisi olduğunu tahmin ediyorum.
Joe Z.

Tamam anladım. Odb boş ama yine de bildirildiğinden, test prosedürünüzdeki son satır bir hata atmaz - ön test değerlerini olması gerektiği gibi ndb'ye geri yüklemek yerine yalnızca sessizce güncellenir. Bu nedenle, tüm test değişiklikleri ndb'ye bağlı kalır ve bu nedenle, jSWlMMkod her çalıştırıldığında 123456 (hash olan ) hesabı bir dolar olarak kredilendirilir.
Joe Z.

Ve makul reddedebilme o nihai kaçırmış olabilir ki Cuma öğleden sonra açıklama geliyor odbo şans için db. Ancak, o 20 Ekim Cuma günü hiç yoktu, aslında Pazartesi günüydü ve hafta yeni başlamıştı. Bu nedenle, bu RJO arkadaşının, daha sonra bunları tekrar yazmış olsa bile, ilk olarak bir üretim veritabanında testler yapmak için ciddi bir kod denetimine ihtiyacı olacağını düşünüyorum.
Joe Z.

@Joe Z Haha, evet, parayı "tıpkı bir test gibi" hareket ettirmek gerçek kodda gerçekten kötü bir fikir. Yapmak için makul bir yol bulmaya çalışıyordum db[hash('jSWlMM')] += 1. Ben bir değişken isimlendirme jSWlMMve "yanlışlıkla" bir şekilde alıntı düşündüm , ama bu Python PHP daha yapmak daha zordur (burada $sigil bırakarak tanımlanamayan bir sabit haline döner, daha sonra bir dize değişmez olarak kabul edilir).
Remy

Bir şeyleri araştırmaya çalışmak eğlenceliydi, ama ben sana bunu vereceğim.
Joe Z.

1

Peki buna ne dersin ?

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

Ölçek:

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

Geri izleme (en son çağrı son): <module> sayımında "test.py", satır 12, dosya [-1] + = 1 TypeError: 'str' ve 'int' nesnelerini birleştiremezsiniz
ErlVolton

1
Orada da bir hata alıyorum. Bu, (bildiğim kadarıyla) Python'da tanımlanmamış davranış olan bir sözlüğün sırasına dayanır.
Emil
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.