Skip to content

Instantly share code, notes, and snippets.

@samscott89

samscott89/max-client.py Secret

Last active Apr 23, 2021
Embed
What would you like to do?
Oso work sample - implementing "Max"
import argparse
import requests
from dataclasses import asdict, dataclass
@dataclass
class Compare:
request_id: int
left: int
right: int
type: str = "compare"
@dataclass
class ComparisonResult:
request_id: int
answer: bool
type: str = "comp_result"
@dataclass
class ComputeMax:
length: int
type: str = "compute_max"
@dataclass
class ComputeMin:
length: int
type: str = "compute_min"
@dataclass
class Done:
result: int
type: str = "done"
def message_to_struct(message):
if message["type"] == "compare":
return Compare(**message)
elif message["type"] == "comp_result":
return ComparisonResult(**message)
elif message["type"] == "compute_min":
return ComputeMin(**message)
elif message["type"] == "compute_max":
return ComputeMax(**message)
elif message["type"] == "done":
return Done(**message)
class Client:
def __init__(self, address, log=False):
self.address = address if address else "http://localhost:5000"
self.log = log
def send(self, data):
response = requests.post(self.address, json=asdict(data))
json = response.json()
if self.log:
print(json)
return message_to_struct(json)
def compute(self, values, op):
req = None
if op == "min":
req = ComputeMin(len(values))
elif op == "max":
req = ComputeMax(len(values))
else:
assert False, "not supported operation: " + op
next_message = self.send(req)
while True:
if next_message.type == "done":
return values[next_message.result]
elif next_message.type == "compare":
request_id = next_message.request_id
left = next_message.left
right = next_message.right
next_message = self.send(ComparisonResult(request_id, values[left] < values[right]))
else:
raise Exception("Unexpected message: ", next_message)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Run the max computer')
parser.add_argument('--address', type=str, required=False,
help='address of the max computer (defaults to http://localhost:5000)')
args = parser.parse_args()
client = Client(args.address, log=True)
assert 3 == client.compute([1, 2, 3, 1], op="max")
assert 1 == client.compute([1, 2, 3, 1], op="min")

Oso - Work Sample

The goal of this exercise is to show your problem solving ability within a system with specific constraints.

We are not looking for completeness/correctness or low-level details in this, but a thoughtful approach to the system. This exercise should (a) give you an idea of the types of problems we work on, and (b) provide a good conversation starter for us to discuss other aspects of the system design.

Implement "Max"

The exercise is to build a server that can compute the minimum and maximum of a list of values, given only as input: the length of a list, and an external interface that can compare two indices of the list.

You may use any language for this task, and can make use of existing libraries where appropriate.

Things we care about:

  • How easy it is to understand what the code does.
  • The design of the system. In particular, your code should be sufficiently flexible to extend to new operations.

Extension areas we will discuss in person, which you can think about but shouldn't spend too much time on:

  • Performance/complexity trade offs
  • Any potential footguns/problem areas

Things we don't care about:

  • Implementing data structures

Why is this relevant?

This exercise is designed to replicate the same problem we faced when building the Polar language. We wanted the language to be able to operate over application data coming from any host language (e.g Python, Java, Node.js).

This meant that while the language was evaluating input, it would sometimes need to defer to the host language for answers. However, the host language was also the one driving the execution of the language. To simulate these conditions, we have provided the HTTP client with a similar interface

Requirements

The server must be exposed via an HTTP interface: a single / endpoint that accepts JSON encoded requests as POST requests. The message format is provided alongside a sample client implemented in Python.

The server returns a JSON encoded response message to the client.

Message

All messages have a type field indicating the message type.

The client sends messages:

  • compute_max: has a length field indicating the number of values in the list. type: "compute_max". Example:

    {
        "type": "compute_max",
        "length": 2
    }
    
  • comp_result: has a request_id provided by the server, and an answer field which is the result of left < right, provided by the server compare message. type: "comp_result". Example:

    {
      "type": "comp_result",
      "request_id": 2,
      "answer": true
    }
    

The server should return messages:

  • compare, with a request_id, which is an identifier to track the result of the comparison. And left and right which are the indices of the list being compared. type: "compare". Example:

    {
      "type": "compare",
      "left": 0,
      "right": 1,
      "request_id": 7
    }
    
  • done, which has a result field containing the index of the maximum value in the list. type: "done". Example:

    {
      "type": "done",
      "result": 2,
    }
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment