65 lines
2.5 KiB
Python
65 lines
2.5 KiB
Python
#!/usr/bin/env python3
|
||
"""
|
||
unchanged CLI – only the *r* and the assert on message length moved to encoder
|
||
"""
|
||
import argparse, sys, numpy as np, subprocess, pathlib, os, tempfile
|
||
import encoder, decoder, channel
|
||
|
||
INPUT_FILE = OUTPUT_FILE = None
|
||
|
||
def transmit(msg, C): return encoder.encode_message(msg, C)
|
||
def receive_local(x): return channel.channel(x)
|
||
|
||
def receive_server(x, host, port):
|
||
global INPUT_FILE, OUTPUT_FILE
|
||
if INPUT_FILE:
|
||
in_f, rm_in = INPUT_FILE, False
|
||
np.savetxt(in_f, x)
|
||
else:
|
||
tf = tempfile.NamedTemporaryFile(suffix='.txt', delete=False)
|
||
np.savetxt(tf.name, x); tf.close()
|
||
in_f, rm_in = tf.name, True
|
||
if OUTPUT_FILE:
|
||
out_f, rm_out = OUTPUT_FILE, False
|
||
else:
|
||
fd, out_f = tempfile.mkstemp(suffix='.txt'); os.close(fd); rm_out = True
|
||
|
||
cmd = [sys.executable, str(pathlib.Path(__file__).parent/'client.py'),
|
||
'--input_file', in_f, '--output_file', out_f,
|
||
'--srv_hostname', host, '--srv_port', str(port)]
|
||
try:
|
||
subprocess.run(cmd, check=True)
|
||
Y = np.loadtxt(out_f)
|
||
finally:
|
||
if rm_in and os.path.exists(in_f): os.remove(in_f)
|
||
if rm_out and os.path.exists(out_f): os.remove(out_f)
|
||
return Y
|
||
|
||
def receive(x, mode, host, port):
|
||
return receive_local(x) if mode=='local' else receive_server(x,host,port)
|
||
|
||
def test(msg, n_trials, mode, host, port):
|
||
C, _ = encoder.make_codebook() # r=11 by default
|
||
print(f"Using codebook with {C.shape[0]} codewords, {C.shape[1]} symbols each.")
|
||
ok = 0
|
||
for _ in range(n_trials):
|
||
x = transmit(msg, C)
|
||
print(f"Transmitted {len(x):,} samples (energy={np.dot(x,x):.2f})")
|
||
y = receive(x, mode, host, port)
|
||
print(f"Received {len(y):,} samples (energy={np.dot(y,y):.2f})")
|
||
est, _ = decoder.decode_blocks_with_state(y, C)
|
||
if est == msg: ok += 1
|
||
print(f"{ok}/{n_trials} perfect decodes ({100*ok/n_trials:.2f}%)")
|
||
|
||
def _args():
|
||
p=argparse.ArgumentParser()
|
||
p.add_argument('-m','--message',required=True,help='exactly 40 chars')
|
||
p.add_argument('-n','--trials', type=int, default=200)
|
||
p.add_argument('--mode',choices=['local','server'],default='local')
|
||
p.add_argument('--hostname',default='iscsrv72.epfl.ch'); p.add_argument('--port',type=int,default=80)
|
||
p.add_argument('-i','--input_file'); p.add_argument('-o','--output_file')
|
||
return p.parse_args()
|
||
|
||
if __name__=='__main__':
|
||
a=_args(); INPUT_FILE=a.input_file; OUTPUT_FILE=a.output_file
|
||
test(a.message, a.trials, a.mode, a.hostname, a.port)
|