diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0416f32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +#emacs backups +*~ \ No newline at end of file diff --git a/q-rel-alt-bit-1/run b/q-rel-alt-bit-1/run new file mode 100755 index 0000000..d50c47f --- /dev/null +++ b/q-rel-alt-bit-1/run @@ -0,0 +1,50 @@ +#!/bin/python3 + + +from inginious import input, feedback, rst + +# random input +b = int(input.get_input("@random")[0] * 200 + 100) #kbps +d = int(input.get_input("@random")[1] * 20 + 20) #msec + + +def isfloat(value): + try: + float(value) + return True + except: + return False + +def almost(answer,value): + if((answer<=(value+value/20)) and (answer>=(value-value/20))): + return True + else: + return False + +bandwidth=b*1000 +dframe=10000 +cframe=100 +delay=d/1000 +throughput=dframe/(dframe/bandwidth+delay+cframe/bandwidth+delay)/8 # bytes/sec +answer = input.get_input("q1") +if(isfloat(answer)): + if (almost(float(answer),throughput)): + feedback.set_problem_result("success","q1") + feedback.set_problem_feedback("Correct","q1") + feedback.set_grade(100) + feedback.set_global_result("success") + else: + feedback.set_problem_result("failed","q1") + response="Your answer is incorrect.\n" + if(almost(float(answer),8*throughput)): + response+="Remember that a byte contains 8 bits. Your answer is close to a throughput expressed in bits/second and not bytes/seconds\n" + if(almost(float(answer),throughput/2)): + response+="Remember that the propagation delay affects the transmission of both the data and control frames\n" + feedback.set_problem_feedback(response,"q1") + feedback.set_grade(0) + feedback.set_global_result("failed") +else: + feedback.set_problem_result("failed","q1") + feedback.set_problem_feedback("Your answer is not a number","q1") + feedback.set_grade(0) + feedback.set_global_result("failed") diff --git a/q-rel-alt-bit-1/task.yaml b/q-rel-alt-bit-1/task.yaml new file mode 100755 index 0000000..bbffeec --- /dev/null +++ b/q-rel-alt-bit-1/task.yaml @@ -0,0 +1,65 @@ +accessible: true +author: Olivier Bonaventure +categories: [] +context: |- + The alternating bit protocol is described in section `Recovering from transmission errors `_ + + .. raw:: html + + +environment: pyjavacpp +evaluate: best +file: '' +groups: false +input_random: '2' +limits: + time: '30' + output: '2' + memory: '100' +name: Alternating Bit Protocol +network_grading: false +order: 16 +problems: + q1: + name: Performance of the alternating bit protocol + default: '' + header: |4- + + + .. raw:: html + + Consider an implementation of the alternating bit protocol that is used on between two hosts that are connected via a direct link. That link has a bandwidth of kbps and a propagation delay of msec. + + + If the data frames are 10,000 bits long and the control frames 100 bits long, what is the maximum throughput achieved by this protocol expressed in bytes/sec? + type: code_single_line +run_cmd: '' +stored_submissions: 0 +submission_limit: + amount: -1 + period: -1 +weight: 1.0 diff --git a/q-rel-alt-bit-2/run b/q-rel-alt-bit-2/run new file mode 100755 index 0000000..45d1d5b --- /dev/null +++ b/q-rel-alt-bit-2/run @@ -0,0 +1,48 @@ +#!/bin/python3 + + +from inginious import input, feedback + +# random input +delay = int(input.get_input("@random")[0] * 7 + 2) +timer = int(input.get_input("@random")[1] * 200 + 100) + + +def isfloat(value): + try: + float(value) + return True + except: + return False + +def almost(answer,value): + if((answer<=(value+value/20)) and (answer>=(value-value/20))): + return True + else: + return False + +sol=11*delay*2+timer + +answer = input.get_input("q1") +if(isfloat(answer)): + if (almost(float(answer),sol)): + feedback.set_problem_result("success","q1") + feedback.set_problem_feedback("Correct","q1") + feedback.set_grade(100) + feedback.set_global_result("success") + else: + feedback.set_problem_result("failed","q1") + response="Your answer is incorrect.\n" + if(float(answer)<10): + response+="Remember that a byte contains 8 bits. To transmit 15000 bytes, the sender needs to send 10 frames.\n" + if(almost(float(answer),10*delay)): + response+="If the third frame is lost, it needs to be retransmitted. Your answer does not consider this retransmission.\n" + feedback.set_problem_feedback(response,"q1") + feedback.set_grade(0) + feedback.set_global_result("failed") +else: + feedback.set_problem_result("failed","q1") + feedback.set_problem_feedback("Your answer is not a number","q1") + feedback.set_grade(0) + feedback.set_global_result("failed") + diff --git a/q-rel-alt-bit-2/task.yaml b/q-rel-alt-bit-2/task.yaml new file mode 100755 index 0000000..fbd8f2c --- /dev/null +++ b/q-rel-alt-bit-2/task.yaml @@ -0,0 +1,62 @@ +accessible: true +author: Olivier Bonaventure +categories: [] +context: |- + .. raw:: html + + +environment: default +evaluate: best +file: '' +groups: false +input_random: '2' +limits: + time: '30' + output: '2' + memory: '100' +name: Alternating Bit Protocol +network_grading: false +order: 18 +problems: + q1: + name: Alternating Bit Protocol in the presence of losses. + default: '' + header: |4+ + + .. raw:: html + + Consider the utilisation of the Alternating Bit Protocol to transfer 15000 bytes of data. Both hosts are connected via a 1 Gbps link and there is a one-way delay of msec between the two hosts. The sender sends data frames that are 12000 bits long. Assuming that the retransmission timer is set to msec, how long does it take to transfer the 15000 bytes if the third data frame is lost ? + + + + type: code_single_line +run_cmd: '' +stored_submissions: 0 +submission_limit: + amount: -1 + period: -1 +weight: 1.0 diff --git a/q-rel-alt-bit-2/test/submission-ko.test b/q-rel-alt-bit-2/test/submission-ko.test new file mode 100644 index 0000000..feba7f8 --- /dev/null +++ b/q-rel-alt-bit-2/test/submission-ko.test @@ -0,0 +1,31 @@ +_id: 5d7815efeadd8a8905fff132 +archive: 5d7815f0eadd8a8905fff133 +courseid: cnp3 +custom: {} +grade: 100.0 +input: + '@lang': en + '@random': + - 0.8060389968499849 + - 0.4098167679928465 + '@random_0': '0.8060389968499849' + '@random_1': '0.4098167679928465' + '@state': '' + '@username': obonaventure + q1: '333' +problems: + q1: + - success + - Correct +response_type: rst +result: success +state: '' +status: done +stderr: '' +stdout: '' +submitted_on: 2019-09-10 23:30:23.215000 +taskid: q-rel-alt-bit-2 +tests: {} +text: '' +username: +- obonaventure diff --git a/q-rel-alt-bit-2/test/submission-ok.test b/q-rel-alt-bit-2/test/submission-ok.test new file mode 100644 index 0000000..feba7f8 --- /dev/null +++ b/q-rel-alt-bit-2/test/submission-ok.test @@ -0,0 +1,31 @@ +_id: 5d7815efeadd8a8905fff132 +archive: 5d7815f0eadd8a8905fff133 +courseid: cnp3 +custom: {} +grade: 100.0 +input: + '@lang': en + '@random': + - 0.8060389968499849 + - 0.4098167679928465 + '@random_0': '0.8060389968499849' + '@random_1': '0.4098167679928465' + '@state': '' + '@username': obonaventure + q1: '333' +problems: + q1: + - success + - Correct +response_type: rst +result: success +state: '' +status: done +stderr: '' +stdout: '' +submitted_on: 2019-09-10 23:30:23.215000 +taskid: q-rel-alt-bit-2 +tests: {} +text: '' +username: +- obonaventure diff --git a/q-rel-checksum/run b/q-rel-checksum/run new file mode 100755 index 0000000..8612394 --- /dev/null +++ b/q-rel-checksum/run @@ -0,0 +1,55 @@ +#!/bin/python3 + + +from inginious import input, feedback, rst +import array + +# random input + +f = int(input.get_input("@random")[0] * 1000000000 + 1000000000) + +# source: https://stackoverflow.com/questions/1767910/checksum-udp-calculation-python +def checksum(pkt): + if len(pkt) % 2 == 1: + pkt += "\0" + s = sum(array.array("H", pkt)) + s = (s >> 16) + (s & 0xffff) + s += s >> 16 + s = ~s + return (((s>>8)&0xff)|s<<8) & 0xffff + +#source https://wiki.python.org/moin/BitManipulation +def bin(s): + return str(s) if s<=1 else bin(s>>1) + str(s&1) + +answer = input.get_input("q1") +a=int(answer,2) + + +fs=f.to_bytes(4,byteorder='big') +fa=a.to_bytes(4,byteorder='big') + +if(f==a): + feedback.set_problem_result("failed","q1") + feedback.set_grade(0) + feedback.set_global_result("failed") + feedback.set_problem_feedback("This is the same frame, you did not modify any bit. The checksum of this frame is "+str(bin(checksum(fs))),"q1") +else: + + if(len(bin(f))!=len(answer)): + feedback.set_problem_result("failed","q1") + feedback.set_grade(0) + feedback.set_global_result("failed") + feedback.set_problem_feedback("The frame that you proposed that does not have the same length as the original one.","q1") + else: + if(checksum(fs)==checksum(fa)): + feedback.set_problem_result("success","q1") + feedback.set_grade(100) + feedback.set_global_result("success") + feedback.set_problem_feedback("The checksum of this frame is "+bin(checksum(fs))+" and the checksum of your answer is "+bin(checksum(fa)),"q1") + else: + feedback.set_problem_result("failed","q1") + feedback.set_grade(0) + feedback.set_global_result("failed") + ret="The checksum of this frame is "+bin(checksum(fs))+" while the checksum of your answer is "+bin(checksum(fa)) + feedback.set_problem_feedback(ret,"q1") diff --git a/q-rel-checksum/task.yaml b/q-rel-checksum/task.yaml new file mode 100755 index 0000000..2eccc86 --- /dev/null +++ b/q-rel-checksum/task.yaml @@ -0,0 +1,37 @@ +accessible: false +author: Olivier Bonaventure +context: 'Internet checksums and CRCs have different error detection capabilities. ' +environment: pyjavacpp +evaluate: best +groups: false +input_random: '1' +limits: + memory: '100' + output: '2' + time: '30' +name: Checksums and CRCs +network_grading: false +problems: + q1: + header: |+ + .. raw:: html + + Consider a simple frame that is represented as the following bitstring : + + Can you find a bitstring that is different from this frame but has the same checksum ? + + + + name: Internet checksum + default: '' + type: code_single_line +stored_submissions: 0 +submission_limit: + amount: -1 + period: -1 +tags: {} +weight: 1.0 +order: 5 diff --git a/q-rel-delay/run b/q-rel-delay/run new file mode 100755 index 0000000..50c9f9d --- /dev/null +++ b/q-rel-delay/run @@ -0,0 +1,47 @@ +#!/bin/python3 + + +from inginious import input, feedback, rst + +# random input +bw = 10000*int(input.get_input("@random")[0] * 100 + 1) #bps +de = int(input.get_input("@random")[1] * 50 + 20) #msec +fl = 100*int(input.get_input("@random")[2] * 10 + 10) #bytes + +def isfloat(value): + try: + float(value) + return True + except: + return False + +def almost(answer,value): + if((answer<=(value+value/20)) and (answer>=(value-value/20))): + return True + else: + return False + +delay=de+(fl*8/bw)*1000 + +answer = input.get_input("q1") +if(isfloat(answer)): + if (almost(float(answer),delay)): + feedback.set_problem_result("success","q1") + feedback.set_problem_feedback("Correct","q1") + feedback.set_grade(100) + feedback.set_global_result("success") + else: + feedback.set_problem_result("failed","q1") + response="Your answer is incorrect.\n" + if(almost(float(answer),delay-de)): + response+="Remember that the electrical/optical signal corresponding to each bit needs to travel from the sender to the receiver. \n" + if(almost(float(answer),de+(fl/bw)*1000)): + response+="Remember that the frame length is specified in bytes while bandwidth is specified in bits per seconde. One byte corresponds to 8 bits.\n" + feedback.set_problem_feedback(response,"q1") + feedback.set_grade(0) + feedback.set_global_result("failed") +else: + feedback.set_problem_result("failed","q1") + feedback.set_problem_feedback("Your answer is not a number","q1") + feedback.set_grade(0) + feedback.set_global_result("failed") diff --git a/q-rel-delay/task.yaml b/q-rel-delay/task.yaml new file mode 100755 index 0000000..b24b8af --- /dev/null +++ b/q-rel-delay/task.yaml @@ -0,0 +1,64 @@ +accessible: true +author: Olivier Bonaventure +categories: [] +context: |- + .. raw:: html + + +environment: pyjavacpp +evaluate: best +file: '' +groups: false +input_random: '3' +limits: + time: '30' + output: '2' + memory: '100' +name: Transfert delay of one frame +network_grading: false +problems: + q1: + name: How long does it take to deliver a frame ? + default: '' + header: | + .. raw:: html + + Consider a bits per second link between two hosts that has a propagation delay of milliseconds. What is the delay (in milliseconds) between the transmission of the first bit of a bytes frame from a sending host and the reception of the last bit of this segment on the receiving host. + + + + type: code_single_line +run_cmd: '' +stored_submissions: 0 +submission_limit: + amount: -1 + period: -1 +weight: 1.0 +order: 6 diff --git a/q-rel-delay1/run b/q-rel-delay1/run new file mode 100755 index 0000000..a094ad8 --- /dev/null +++ b/q-rel-delay1/run @@ -0,0 +1,79 @@ +#!/bin/python3 + + +from inginious import input, feedback, rst + +# random input +km = 10*int(input.get_input("@random")[0] * 200 + 10) #km +bw = int(input.get_input("@random")[1] * 50 + 5) # Mbps + + +def isfloat(value): + try: + float(value) + return True + except: + return False + +def almost(answer,value): + if((answer<=(value+value/20)) and (answer>=(value-value/20))): + return True + else: + return False + +# length of data frame +dlen=1000 +# length of control frame +clen=40 +#propagation delay in msec +prop=km*5/1000 + + +rtt=1000*(dlen/(bw*1000000)+0.0001+clen/(bw*1000000)+2*prop) + +grade=0 +answer1 = input.get_input("q1") +answer2 = input.get_input("q2") + + +if(isfloat(answer1)): + if (almost(float(answer1),prop)): + feedback.set_problem_result("success","q1") + feedback.set_problem_feedback("Correct","q1") + grade+=30 + else: + feedback.set_problem_result("failed","q1") + response="Your answer is incorrect.\n" + if(almost(float(answer1),1000*prop)): + response+="Remember that propagation delay is in microseconds per kilometer while your answer must be in milliseconds.\n" + feedback.set_problem_feedback(response,"q1") + else: + feedback.set_problem_result("failed","q1") + feedback.set_problem_feedback("Your answer is not a number","q1") + + +if(isfloat(answer2)): + if (almost(float(answer2),rtt)): + feedback.set_problem_result("success","q2") + feedback.set_problem_feedback("Correct","q2") + grade+=70 + else: + feedback.set_problem_result("failed","q2") + response="Your answer is incorrect.\n" + if(almost(float(answer2),1000*rtt)): + response+="Remember that the round-trip-time must be expressed in milliseconds.\n" + if(almost(float(answer2),rtt-2*prop)): + response+="Remember that the round-trip-time includes both the time to transmit the data and control frames and twice the propagation delay.\n" + + feedback.set_problem_feedback(response,"q2") +else: + feedback.set_problem_result("failed","q2") + feedback.set_problem_feedback("Your answer is not a number.","q2") + + + +feedback.set_grade(grade) +if(grade>50): + feedback.set_global_result("success") +else: + feedback.set_global_result("failed") diff --git a/q-rel-delay1/task.yaml b/q-rel-delay1/task.yaml new file mode 100755 index 0000000..08215f3 --- /dev/null +++ b/q-rel-delay1/task.yaml @@ -0,0 +1,71 @@ +accessible: true +author: Olivier Bonaventure +categories: [] +context: |- + .. raw:: html + + +environment: pyjavacpp +evaluate: best +file: '' +groups: false +input_random: '2' +limits: + time: '30' + output: '2' + memory: '100' +name: Round trip time +network_grading: false +problems: + q1: + name: Transmission delay + default: '' + header: |- + .. raw:: html + + Consider two hosts connected by a physical cable. The two hosts are separated by a distance of kilometers and the propagation delay is 5 microseconds per kilometer. What is the delay required to send one bit from the sender to the receiver (in milliseconds) ? + + + type: code_single_line + q2: + header: |- + .. raw:: html + + If the bandwidth of this physical cable is Mbps. If the data frames have a length of 1000 bits and the acknowledgments a length of 40 bits, what is the exact value of the round-trip-time, i.e. the delay in seconds between the transmission of the first bit of a data frame and the reception of the last bit of the acknowledgment ? To compute this delay, you can assume that the receiver needs one millisecond to verify a received frame and prepare the corresponding acknowledgment. + + + default: '' + name: Round trip time + type: code_single_line +run_cmd: '' +stored_submissions: 0 +submission_limit: + amount: -1 + period: -1 +weight: 1.0 +order: 7 diff --git a/q-rel-gbn-max/run b/q-rel-gbn-max/run new file mode 100755 index 0000000..76c2040 --- /dev/null +++ b/q-rel-gbn-max/run @@ -0,0 +1,44 @@ +#!/bin/python3 + + +from inginious import input, feedback, rst + +# random input +n = int(input.get_input("@random")[0] * 17 + 3) + +def isfloat(value): + try: + float(value) + return True + except: + return False + + +answer = int(input.get_input("q1")) +sol=(2**n)-1 +grade=0 + +if(isfloat(answer)): + if(answer==sol): + feedback.set_problem_result("success","q1") + feedback.set_problem_feedback("Correct","q1") + grade+=100 + else: + feedback.set_problem_result("failed","q1") + response="Your answer is incorrect.\n" + if(answer==2**n): + response+="Remember that the go-back-n sender cannot transmit all the 2^n sequences number in a row. /n" + if(answer==2**(n-1)): + response+="Do not confuse go-back-n and selective repeat. Selective repeat needs to use a smaller window because the receiver stores out-of-order frames in its buffers./n" + + feedback.set_problem_feedback(response,"q1") +else: + feedback.set_problem_result("failed","q1") + feedback.set_problem_feedback("Your answer is not a number","q1") + + +feedback.set_grade(grade) +if(grade>50): + feedback.set_global_result("success") +else: + feedback.set_global_result("failed") diff --git a/q-rel-gbn-max/task.yaml b/q-rel-gbn-max/task.yaml new file mode 100755 index 0000000..10bdc9f --- /dev/null +++ b/q-rel-gbn-max/task.yaml @@ -0,0 +1,59 @@ +accessible: true +author: Olivier Bonaventure +categories: [] +context: |- + .. raw:: html + + +environment: pyjavacpp +evaluate: best +file: '' +groups: false +input_random: '1' +limits: + time: '30' + output: '2' + memory: '100' +name: Maximum window size for Go-back-n +network_grading: false +problems: + q1: + name: 'Maximum window size ' + default: '' + header: |- + .. raw:: html + + Consider a go-back-n protocol that uses a frame that contains bits to encode the sequence number. What is the maximum number of frames that a sender can send before being forced to wait for an acknowledgment ? + + + type: code_single_line +regenerate_input_random: 'on' +run_cmd: '' +stored_submissions: 0 +submission_limit: + amount: -1 + period: -1 +weight: 1.0 +order: 8 diff --git a/q-rel-sr-max/run b/q-rel-sr-max/run new file mode 100755 index 0000000..44230eb --- /dev/null +++ b/q-rel-sr-max/run @@ -0,0 +1,44 @@ +#!/bin/python3 + + +from inginious import input, feedback, rst + +# random input +n = int(input.get_input("@random")[0] * 17 + 3) + +def isfloat(value): + try: + float(value) + return True + except: + return False + + +answer = int(input.get_input("q1")) +sol=(2**(n-1)) +grade=0 + +if(isfloat(answer)): + if(answer==sol): + feedback.set_problem_result("success","q1") + feedback.set_problem_feedback("Correct","q1") + grade+=100 + else: + feedback.set_problem_result("failed","q1") + response="Your answer is incorrect.\n" + if(answer==2**n): + response+="Remember that the selective repeat sender cannot transmit all the 2^n sequences number in a row. /n" + if(answer==(2**n)-1): + response+="Do not confuse go-back-n and selective repeat. Selective repeat needs to use a smaller window because the receiver stores out-of-order frames in its buffers./n" + + feedback.set_problem_feedback(response,"q1") +else: + feedback.set_problem_result("failed","q1") + feedback.set_problem_feedback("Your answer is not a number","q1") + + +feedback.set_grade(grade) +if(grade>50): + feedback.set_global_result("success") +else: + feedback.set_global_result("failed") diff --git a/q-rel-sr-max/task.yaml b/q-rel-sr-max/task.yaml new file mode 100755 index 0000000..ea5924c --- /dev/null +++ b/q-rel-sr-max/task.yaml @@ -0,0 +1,59 @@ +accessible: true +author: Olivier Bonaventure +categories: [] +context: |- + .. raw:: html + + +environment: pyjavacpp +evaluate: best +file: '' +groups: false +input_random: '1' +limits: + time: '30' + output: '2' + memory: '100' +name: Maximum window size for Selective repeat +network_grading: false +problems: + q1: + name: 'Maximum window size ' + default: '' + header: |- + .. raw:: html + + Consider a selective repeat protocol that uses a frame that contains bits to encode the sequence number. What is the maximum number of frames that a sender can send before being forced to wait for an acknowledgment ? + + + type: code_single_line +regenerate_input_random: 'on' +run_cmd: '' +stored_submissions: 0 +submission_limit: + amount: -1 + period: -1 +weight: 1.0 +order: 9