程序代写案例-00PM

欢迎使用51辅导,51作业君孵化低价透明的学长辅导平台,服务保持优质,平均费用压低50%以上! 51fudao.top
V&V: Design by Contract Coursework
Due March 15, 2021 @ 4:00PM (UK time)
(5% of the Total Course Mark)
Use iContract, a Design by Contract library for Python3, and two Python3’s standard
libraries — xmlrpc and threading, to implement a client-server banking application.
This application has three parts: a server, clients, and a test harness.
Server
The server supports the following operations
1. openAccount
2. closeAccount
3. deposit
4. withdraw
5. changeAddress
6. changePassword
7. resetPassword (for lost or forgotten
passwords)
8. transfer
9. cancelTransfer
10. getStatements
11. listAccounts
The listAccounts operation is not realistic, of course, because it violates privacy, but we
need it in this coursework to support transfers without needless complexity. Another
simplification, in addition to listAccounts, is that users can have only one account. This
server must correctly handle concurrent calls to its operations.
Client
Each client takes a starting amount of money to deposit and a probability distribution
over the server’s banking operations, augmented with the special operation noAction,
which, as its name suggests, does nothing. Each client starts by opening an account and
depositing money. It then loops using its probability distribution to select operations,
which it performs concurrently to other clients, until the harness kills it. The clients must
correctly handle errors, like attempting to withdraw more money than it has.
Action distribution: Server supports 11 operations, which grows to 12 with noAction.
For this assignment, therefore, a client probability distribution is a list of 12 floats that
sum to 1. This list assigns probabilities to the actions above in order, again augmented
with noAction. Thus, the first element of the list is the probability of an account opening
and the last element is the probability that the client takes no action.
1
import bisect
import random
x = random.uniform(0, 1)
probs = [0.1, 0.4, 0.3, 0.2]
intervals = [sum(probs[:i+1]) for i in range(len(probs))]
bisect.bisect_right(intervals, x)
Harness
The harness takes a number of clients to create, a list of action distributions to use when
creating each client, and a bound on the simulation. It should default to creating two
clients with a reasonable probability distribution over actions, i.e. one which favours
deposits over closing accounts.
Assessment
We will manually assess your submission. Be sure to meet the following require-
ments:
1. When we statically check your submission for errors using pyicontract-lint, it
should be clean.
2. Your submission must include a test suite written using Hypothesis and its icon-
tract integration.
3. DbC does not require loop invariants. Nonetheless, for this assignment, formulate
loop invariants for each loop in each component in your coursework.
Do not publish your solution to GitHub or any similar platform, even after the module
completes. You are, of course, welcome, even encouraged, to use private repos for this
coursework.
2
Appendix: Guidance for icontract, threading, and xm-
prlc
icontract
The installation of iContract is straightforward: install icontract using pip with sudo:
sudo pip3 install icontract
Here is a brief example of icontract:
import icontract
@icontract.require(lambda x: x < 3)
def some_func(x: int, y: int = 5):
print(x)
some_func(2)
threading
threading is a python built-in module, so it comes with python. Here is an example of
how parallelism is handled using the threading package.
import time
import threading
# create the lock
lock = threading.Lock()
# define a global resource
global_resource = [None] * 5
def change_resource(para, sleep):
# request the lock
lock.acquire()
global global_resource
for i in range(len(global_resource)):
global_resource[i] = para
time.sleep(sleep)
print("global_resource to be:", global_resource)
# release the lock
lock.release()
def main():
thread_hi = threading.Thread(target = change_resource, args = ("hi", 2))
thread_hello = threading.Thread(target = change_resource, args = ("hello",
1))
thread_hi.start()
thread_hello.start()
if __name__ == ’__main__’:
main()
3
xmlrpc
xmlrpc is also a python built-in module, so it is installed along with python. The
scripts below are two examples showing how xmlrpc works together with icontract and
threading packages.
serverSample.py
from xmlrpc.server import SimpleXMLRPCServer
import icontract
import time
import threading
# create a random function
def add(balance, deposit):
return balance + deposit
@icontract.require(lambda x: x < 3)
def some_func(x, y):
return 2 * x + y
# create the lock
lock = threading.Lock()
# define a global resource
global_resource = [None] * 5
def change_resource(para, sleep):
# request the lock
lock.acquire()
global global_resource
for i in range(len(global_resource)):
global_resource[i] = para
time.sleep(sleep)
print("global_resource to be:", global_resource)
# release the lock
lock.release()
def lock_test():
thread_hi = threading.Thread(target = change_resource, args = ("hi", 2))
thread_hello = threading.Thread(target = change_resource, args = ("hello",
1))
thread_hi.start()
thread_hello.start()
# test the xmlrpc server
if __name__ == ’__main__’:
s = SimpleXMLRPCServer((’127.0.0.1’, 9000), allow_none = True)
s.register_introspection_functions()
# register the functions of "add", "pow", "some_func" and "lock_test "to the
server
s.register_function(add)
s.register_function(pow)
4
s.register_function(some_func)
s.register_function(lock_test)
# start the main loop of the server
s.serve_forever()
clientSample.py
from xmlrpc.client import ServerProxy
if __name__ == ’__main__’:
# create a client instance
s = ServerProxy("http://127.0.0.1:9000")
print(s.system.listMethods())
# execute functions
print(s.add(100, 101))
print(s.pow(2, 5))
print(s.some_func(5, 5))
print(s.lock_test())
We can run serverSample.py in terminal 1 and run clientSample.py in terminal 2. If, in
the clientSample.py we have some_func(x = 2,y = 5) and the precondition x < 3, the
running outputs for server and client terminals follow:
terminal 1
127.0.0.1 - - [17/Feb/2021 01:09:41] "POST /RPC2 HTTP/1.1" 200 -
127.0.0.1 - - [17/Feb/2021 01:09:41] "POST /RPC2 HTTP/1.1" 200 -
127.0.0.1 - - [17/Feb/2021 01:09:41] "POST /RPC2 HTTP/1.1" 200 -
127.0.0.1 - - [17/Feb/2021 01:09:41] "POST /RPC2 HTTP/1.1" 200 -
127.0.0.1 - - [17/Feb/2021 01:09:41] "POST /RPC2 HTTP/1.1" 200 -
global_resource to be: [’hi’, ’hi’, ’hi’, ’hi’, ’hi’]
global_resource to be: [’hello’, ’hello’, ’hello’, ’hello’, ’hello’]
terminal 2
[’add’, ’lock_test’, ’pow’, ’some_func’, ’system.listMethods’,
’system.methodHelp’, ’system.methodSignature’]
201
32
9
None
And if, in the clientSample.py, we have some_func(x= 5,y= 5), then the running outputs
for the terminals are:
terminal 1
127.0.0.1 - - [17/Feb/2021 01:11:30] "POST /RPC2 HTTP/1.1" 200 -
127.0.0.1 - - [17/Feb/2021 01:11:30] "POST /RPC2 HTTP/1.1" 200 -
127.0.0.1 - - [17/Feb/2021 01:11:30] "POST /RPC2 HTTP/1.1" 200 -
127.0.0.1 - - [17/Feb/2021 01:11:30] "POST /RPC2 HTTP/1.1" 200 -
5
terminal 2
Fault: :File
/home/bingchai/comp0103_2021/serverSample/py, line 17 in :\nx<3: x was
5">
6

欢迎咨询51作业君
51作业君

Email:51zuoyejun

@gmail.com

添加客服微信: abby12468