#Eidetic, Python 2

    import random, math, sys, json
    
    total_degrees, degrees_left, total_people, people_left = map(int, sys.argv[1:])
    #try:
    #    inp_f = open("./data/Eidetic.json", "r")
    #    out = json.load(inp_f)
    #except (IOError, ValueError):
    out = {"last_cake": 0,
               "runs": 0,
               "total_runs": 0,
               "total_rounds": 0,
               "training":  [[0.0], [0.0], [0.12903225806451613], [16.774193548387096], [400.83870967741933], [720.0], [995.8709677419355], [996.9437634408603], [997.6], [997.6], [997.6], [998.5991397849463], [996.6770967741936], [998.8122580645161], [1011.5467420570814], [1017.7717824448034], [1227.155465805062], [1280.7840603123318], [1435.8028540656974], [1553.3689822294023], [1793.5330640818527], [2299.178101402373], [3183.924709689701], [2231.666666666667], [2619.4789644012944], [1270.9288025889969], [741.2718446601941], [480.4757281553398], [122.66990291262135], [27.54736842105263]]}
    
    #else: inp_f.close()
    
    def write_out():
        out_f = open("./data/Eidetic.json", "w")
        out_f.write(json.dumps(out))
        out_f.close()
    
    def get_last_winner(): # Find the bid of the last winner
        bid = out["last_cake"]
        return max(bid, degrees_left) - degrees_left
    
    def train():
    #    print degrees_left # If you get that much, your probably safe.
    #    sys.stderr.write("\nEidetic - Training len %s, no runs: %s, no_rounds: %s, last winner: %s\n"%(len(out["training"]), out["runs"], out["total_rounds"], get_last_winner()))
        if len(out["training"]) <= out["runs"]: out["training"].append([])
        out["training"][out["runs"]].append(get_last_winner())
    
    def get_best_round():
        data = out["training"][out["runs"]+1:]
        mean = [sum(i)/(float(len(i)) or 1) for i in data]
        bid = max(mean+[0]) - 0.5
        sys.stderr.write("\nEidetic - mean %s\n"%mean)
        return bid
    
    def main():
        reset = total_people == people_left
        if reset:
            out["total_rounds"] += 1
            out["runs"] = 0
        train()
        bid = get_best_round()
        print bid
    #    sys.stderr.write('\nEidetic Bid: '+str(bid)+'\n')
        out["total_runs"] += 1
        out["runs"] += 1
        out["last_cake"] = degrees_left
        write_out()
    
    main()

I ran this bot in the controller a couple of times to train it up a bit, it remembers the bids required to win each round and then once trained, it goes out into the real world and votes with the rest of them.