import json
import os
import numpy as np
import tensorflow as tf

from tf_agents.trajectories import policy_step
from tf_agents.trajectories import time_step as ts
from tf_agents.trajectories import trajectory as tf_trajectory

from google.protobuf import text_format

import common.generate_protos  # pylint: disable=unused-import

import action_pb2
import brain_pb2
import episode_pb2
import observation_pb2
import data_store_pb2

from learner.brains import tfa_specs

PROJECT_ID = 'project1'
BRAIN_ID = 'brain1'
SESSION_ID = 'session1'
EPISODE_ID = 'episode1'
ASSIGNMENT_ID = (
    # Choose settings that maximize speed and reduce non-determinism.
    '{"batch_size": 500, "training_examples": 500, "save_interval_batches": 5,'
    ' "synchronous_export": true, "use_xla_jit": false, '
    ' "num_batches_to_sample": 5}')

def populate_data_store(data_store, assignment_id=None, episode_ids=None,
                        steps_per_episode_chunk=None):
  """Populate a datastore with an assignment.

  Args:
    data_store: data_store.DataStore instance to populate.
    assignment_id: Assignment ID to create or ASSIGNMENT_ID if this is None.
    episode_ids: IDs of episodes to create or a single episode with
      EPISODE_ID if this is None.
    steps_per_episode_chunk: List of number of steps for each episode chunk.
      For example, [2, 4] would create two chunks with 2 and 4 steps
      respectively. If this is None, this argument defaults to [2, 2].

  Returns:
    (assignment_resource_id, episode_chunk_resource_ids) where
    assignment_resource_id is resource ID of the written assignment and
    episode_chunk_resource_ids is a list of episode chunk resource IDs written
    to the data store.
  """
  assignment_proto = assignment(assignment_id=assignment_id)
  assignment_resource_id = data_store.to_resource_id(assignment_proto)
  protos = [
      project(),
      data_store_brain(),
      session(),
      assignment_proto,
  ]
  if not steps_per_episode_chunk:
    steps_per_episode_chunk = [2, 2]
  if episode_ids is None:
    episode_ids = [EPISODE_ID]
  episode_chunk_resource_ids = []
  if episode_ids:
    for episode_id in episode_ids:
      for chunk in episode_chunks(steps_per_episode_chunk, episode_id):
        episode_chunk_resource_ids.append(data_store.to_resource_id(chunk))
        protos.append(chunk)
  for proto in protos:
    data_store.write(proto)
  return assignment_resource_id, episode_chunk_resource_ids

def project():
  """Return a test data_store_pb2.Project."""
  return data_store_pb2.Project(project_id=PROJECT_ID)

def data_store_brain():
  """Return a test data_store_pb2.Brain."""
  return data_store_pb2.Brain(
      project_id=PROJECT_ID,
      brain_id=BRAIN_ID,
      brain_spec=brain_spec())

def session():
  """Return a test data_store_pb2.Session."""
  return data_store_pb2.Session(
      project_id=PROJECT_ID,
      brain_id=BRAIN_ID,
      session_id=SESSION_ID)

def create_assignment_id(override_dict):
  """Return the default test assignment id with hparam overrides."""
  assignment_dict = json.loads(ASSIGNMENT_ID)
  assignment_dict.update(override_dict)
  return json.dumps(assignment_dict)

def assignment(assignment_id=None):
  """Returns a test data_store_pb2.Assignment.

  Args:
    assignment_id: Assignment ID string to use or None to use
      ASSIGNMENT_ID.

  Returns:
    data_store_pb2.Assignment instance.
  """
  return data_store_pb2.Assignment(
            project_id=PROJECT_ID,
            brain_id=BRAIN_ID,
            session_id=SESSION_ID,
            assignment_id=(assignment_id if assignment_id else ASSIGNMENT_ID))

def episode_chunks(steps_per_episode_chunk, episode_id):
  """Get example episode chunks.

  Args:
    steps_per_episode_chunk: List of number of steps for each episode chunk.
      For example, [2, 4] would create two chunks with 2 and 4 steps
      respectively.
    episode_id: ID of the episode all chunks belong to.

  Returns:
    List of episode_pb2.EpisodeChunk protos.
  """
  chunk = episode_pb2.EpisodeChunk()
  chunks = []
  step_timestamp = 0
  number_of_chunks = len(steps_per_episode_chunk)
  for chunk_index, chunk_size in enumerate(steps_per_episode_chunk):
    chunk = data_store_pb2.EpisodeChunk(
        project_id=PROJECT_ID,
        brain_id=BRAIN_ID,
        session_id=SESSION_ID,
        episode_id=episode_id,
        chunk_id=chunk_index)
    for _ in range(chunk_size):
      step = episode_pb2.Step()
      step.timestamp_millis = step_timestamp
      step_timestamp += 1000
      step.observation.CopyFrom(observation_data(50, [1, 2, 3]))
      step.action.CopyFrom(action_data(1, 0.3))

      chunk.data.episode_id = episode_id
      chunk.data.chunk_id = chunk_index
      chunk.data.steps.append(step)
      if chunk_index < number_of_chunks - 1:
        chunk.data.episode_state = episode_pb2.IN_PROGRESS
      else:
        chunk.data.episode_state = episode_pb2.SUCCESS
    chunks.append(chunk)

  return chunks

def _read_text_file(filename):
  """Read the contents of a text file relative into a string.

  Args:
    filename: Path to a file relative to this module.

  Returns:
    String contents of the file.
  """
  with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), filename),
            mode='rt') as file_obj:
    return file_obj.read()

def observation_spec():
  """Builds an example ObservationSpec."""
  spec = observation_pb2.ObservationSpec()
  text_format.Parse(_read_text_file('example_model/observation_spec.pbtxt'),
                    spec)
  return spec

def observation_data(health, position):
  """Builds an example ObservationData object."""
  data = observation_pb2.ObservationData()
  text_format.Parse(
      _read_text_file(
          'example_model/observation_data.pbtxt_template').format(
              position0=position[0],
              position1=position[1],
              position2=position[2],
              health=health), data)
  return data

def action_spec():
  """Builds an example ActionSpec."""
  spec = action_pb2.ActionSpec()
  text_format.Parse(_read_text_file('example_model/action_spec.pbtxt'), spec)
  return spec

def action_data(switch_weapon, throttle,
                joy1=None, joy2=None, joy3=None):
  """Builds an example ActionData."""
  joy1 = None or [1.0, 0.0]
  joy2 = None or [0.0, -1.0]
  joy3 = None or [-1.0, 0.5]
  data = action_pb2.ActionData()
  text_format.Parse(
      _read_text_file('example_model/action_data.pbtxt_template').format(
          switch_weapon=switch_weapon,
          throttle=throttle,
          joy1_x_axis=joy1[0],
          joy1_y_axis=joy1[1],
          joy2_x_axis=joy2[0],
          joy2_y_axis=joy2[1],
          joy3_x_axis=joy3[0],
          joy3_y_axis=joy3[1]), data)
  return data

def brain_spec():
  return brain_pb2.BrainSpec(
      observation_spec=observation_spec(),
      action_spec=action_spec())

def brain():
  return data_store_pb2.Brain(
      project_id=PROJECT_ID,
      brain_id=BRAIN_ID,
      name='test_brain',
      brain_spec=brain_spec())

def trajectory(health=100, position=(0, 0, 0), switch_weapon=0, throttle=1.0,
               add_batch_dimension=False):
  """Return a single frame example trajectory.

  Args:
    health: Health to add to the observation. (0.0...100.0)
    position: Position to add to the player entity.
      (3 component tuple of floats)
    switch_weapon: Switch weapon action. (0...4)
    throttle: Throttle action. (-1.0...1.0)
    add_batch_dimension: Whether to add a batch (outer most) dimension of size
      1 around each tensor in the trajectory.

  Returns:
    TF Agents Trajectory instance.
  """
  obs_spec = tfa_specs.ObservationSpec(observation_spec())
  act_spec = tfa_specs.ActionSpec(action_spec())
  obs_data = obs_spec.tfa_value(observation_data(health, position))
  act_data = act_spec.tfa_value(action_data(switch_weapon, throttle))

  act_step = policy_step.PolicyStep(action=act_data)
  reward_array = np.array([0.0], dtype=np.float32)
  discount_array = np.array([0.99], dtype=np.float32)

  time_step = ts.transition(
      obs_data, reward=reward_array, discount=discount_array)
  traj = tf_trajectory.from_transition(
      time_step, act_step, time_step)
  if add_batch_dimension:
    traj = tf.nest.map_structure(lambda tensor: tf.expand_dims(tensor, axis=0),
                                 traj)
  return traj


# linked list
class Node:
    def __init__(self,data):
        self.data = data
        self.next = None

class linkedList:
    def __init__(self):
        self.head = None

    def append(self,data):
        new_node = Node(data)
        # print(type(new_node))
        if not self.head:
            self.head = new_node
        else:
            current = self.head
            while current.next:
                current = current.nect
            current.next = new_node

    def read(self):
        current = self.head
        lst = []
        while current:
            # print(current.data)
            lst.append(current.data)
            current = current.next
        print(lst)

    def update(self,data,target):
        current = self.head
        while current:
            if current.data == target:
                current.data = data
                return
            current = current.next
        else:
            print(f"{target} not found in linked list")

    def delete(self,data):
        if not self.head:
            return

        current = self.head
        if current.data == data:
            self.head = current.next

        while current.next:
            if current.next.data == data:
                current.next = current.next.next
                return
            current = current.next

linked = linkedList()
linked.append(10)
linked.append(14)
linked.update(15,14)
linked.delete(15)
linked.read()


#Initialize two variables as empty and none where we append the values after evaluating each line in the text
highest_gwa = None
highest_student = ""

#Open the txt file as read mode and iterate through each line of txt with for loop
with open("studentgwalist.txt", "r") as file:
    for line in file:
    #Split the each line into two parts, where the first part is the students' name and the second is their GWA
        name, gwa = line.strip().split(" - ")
        gwa = float(gwa)
    # Compare the current GWA value with the highest GWA value
    # If the current GWA is lower than highest_gwa, update highest_gwa and highest_student
    # The lower the value, the higher the GWA
        if highest_gwa is None or gwa < highest_gwa:
            highest_gwa = gwa
    # Update the name to the current highest
            highest_student = name

#Display the output

print("\033[1;34mThe student with the highest GWA of\033[0m", "\033[1;32m" + str(highest_gwa),  "\033[0m" + "\033[1;34mis\033[0m",  "\033[1;32m" + highest_student + "\033[0m")


import seaborn as sns
from utilsJ.Behavior import plotting
from scipy.interpolate import interp1d
from scipy.stats import sem
from matplotlib import cm
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
SAVPATH = '/home/jordi/Documents/changes_of_mind/changes_of_mind_scripts/PAPER/paperfigs/test_fig_scripts/' # where to save figs
SAVEPLOTS = True # whether to save plots or just show them

# util functions

def get_com_ty(row):  # to retrieve time and distance of each CoM
    row = row.copy()
    fps = (row['trajectory_stamps'][-1] - row['trajectory_stamps']
           [0]).astype(int) / (1000 * row.trajectory_stamps.size)

    fixtime = np.datetime64(row['fix_onset_dt'])
    peak_candidates = row['CoM_peakf']
    traj = row['trajectory_y']
    if len(peak_candidates) > 1:  # we know these are not 0s
        correct_peak = peak_candidates[np.where(
            np.abs(traj[peak_candidates]).max())[0]]
        yval = traj[correct_peak]

        if isinstance(row['trajectory_stamps'], np.ndarray):
            tval = (row['trajectory_stamps'][correct_peak] -
                    fixtime).astype(int) / 1000
        else:
            tval = 1000*correct_peak/fps
    else:
        yval = traj[peak_candidates]
        if isinstance(row['trajectory_stamps'], np.ndarray):
            tval = (row['trajectory_stamps'][peak_candidates] -
                    fixtime).astype(int) / 1000
        else:
            tval = 1000*peak_candidates/fps

    return [tval[0], yval[0]]  # tval will be in ms
# tiny one to ensure minor transformations are done? eg. allpriors, normallpriors ----

def a(
        df, average=False,
        rtbins=np.arange(0, 151, 3),
        evidence_bins=np.array([0, 0.15, 0.30, 0.60, 1.05]),
        savpath=SAVPATH):
    """calls tachometric defined in utilsJ.behavior.plotting"""
    # TODO adapt so proper mean/CI are shown when plotting average rat
    f, ax = plt.subplots(figsize=(9, 6))
    f.patch.set_facecolor('white')
    ax.set_facecolor('white')
    if not average:
        tacho_kws = dict(
            rtbins=rtbins,
            labels=[f'sstr {x}' for x in [0, .25, .5, 1]],
            fill_error=True
        )
        plotting.tachometric(df, ax=ax, **tacho_kws)
    else:
        rtbinsize = rtbins[1]-rtbins[0]
        df['rtbin'] = pd.cut(
            df.sound_len,
            rtbins,
            labels=np.arange(rtbins.size-1),
            retbins=False, include_lowest=True, right=True
        ).astype(float)

        evidence_bins = np.array([0, 0.15, 0.30, 0.60, 1.05])
        df['sstr'] = 0
        for i, sst in enumerate([0, .25, .5, 1]):
            df.loc[
                (df.coh2.abs() >= evidence_bins[i])
                & (df.coh2.abs() < evidence_bins[i+1]),
                'sstr'] = sst
        cmap = cm.get_cmap('inferno')
        tmp = (df.groupby(['subjid', 'sstr', 'rtbin'])['hithistory'].mean()
               .reset_index()
               .groupby(['sstr', 'rtbin'])['hithistory'].agg(['mean', sem])
               )
        for i, sst in enumerate(tmp.index.get_level_values(0).unique()):
            ax.plot(
                tmp.loc[sst, 'mean'].index * rtbinsize + 0.5 * rtbinsize,
                tmp.loc[sst, 'mean'],
                marker='o', color=cmap(i/(evidence_bins.size-1))
            )
            ax.fill_between(
                tmp.loc[sst, 'mean'].index * rtbinsize + 0.5 * rtbinsize,
                tmp.loc[sst, 'mean'] + tmp.loc[sst, 'sem'],
                y2=tmp.loc[sst, 'mean'] - tmp.loc[sst, 'sem'],
                alpha=0.3, color=cmap(i/(evidence_bins.size-1))
            )

    sns.despine(ax=ax, trim=True)
    ax.set_ylabel('accuracy', fontsize=14)
    ax.set_xlabel('RT (ms)', fontsize=14)

    if SAVEPLOTS:
        f.savefig(f'{savpath}2a_tachometric.svg')
    plt.show()

def bcd(parentpath, sv_folder=None):
    sv_folder = sv_folder or SAVPATH
    portspng = '/home/molano/Dropbox/project_Barna/' +\
    'ChangesOfMind/figures/Figure_3/ports.png'
    ratcompng = '/home/molano/Dropbox/project_Barna/' +\
        'ChangesOfMind/figures/Figure_3/001965.png'
    img = plt.imread(portspng)
    rat = plt.imread(ratcompng)
    fig, ax = plt.subplots(ncols=3, figsize=(18, 5.5), gridspec_kw={
                           'width_ratios': [1, 1, 1.8]})
    fig.patch.set_facecolor('white')
    #ax[1] = plt.subplot2grid((2,2), (0,0), rowspan=2)
    for i in range(3):
        ax[i].set_facecolor('white')
    ax[0].imshow(np.flipud(rat))
    ax[1].imshow(img)
    for i in [0, 1]:
        ax[i].set_xticklabels([])
        ax[i].set_yticklabels([])
        ax[i].set_xticks([])
        ax[i].set_yticks([])
        ax[i].set_xlabel('x dimension (pixels)', fontsize=14)
        ax[i].set_ylabel('y dimension (pixels)', fontsize=14)

    ax[0].set_xlim(435, 585)
    ax[0].set_ylim(130, 330)
    ax[1].set_xlim(450, 600)
    ax[1].set_ylim(100, 300)

    # a = ComPipe.chom('LE37', parentpath=parentpath)
    # # a.load_available()
    # # load and preprocess data
    # a.load('LE37_p4_u_20190330-150513')
    # a.process(normcoords=True)
    # a.get_trajectories()
    # a.suggest_coms()
    # a.trial_sess['t_com'] = [[np.nan, np.nan]]*len(a.trial_sess)
    # a.trial_sess['y_com'] = np.nan
    # a.trial_sess.loc[
    #     (a.trial_sess.resp_len < 2) & (a.trial_sess.CoM_sugg == True),
    #     't_com'
    # ] = a.trial_sess.loc[
    #     (a.trial_sess.resp_len < 2) & (a.trial_sess.CoM_sugg == True)
    # ].apply(lambda x: get_com_ty(x), axis=1)  # peak is just available for CoM trials# 'framerate'
    # a.trial_sess[['t_com', 'y_com']] = pd.DataFrame(
    #     a.trial_sess['t_com'].values.tolist(), index=a.trial_sess.index)

    # a.trial_sess['ftraj'] = np.nan
    # a.trial_sess['ftraj'] = a.trial_sess.trajectory_y.apply(lambda x: len(x))

    # for i in range(205, 220):  # 235):

    #     if a.trial_sess.dirty[i] or ((a.trial_sess.CoM_sugg[i] == True) & (a.trial_sess.y_com.abs()[i] < 7)):
    #         print(f'skipping {i}')
    #         continue

    #     if a.trial_sess.R_response[i]:
    #         toappendx, toappendy = [-20], [75]
    #     else:
    #         toappendx, toappendy = [-20], [-75]

    #     # c_resp_len = a.trial_sess.resp_len[i]
    #     c_sound_len = a.trial_sess.sound_len[i]
    #     tvec = (
    #         a.trial_sess.trajectory_stamps[i] -
    #         np.datetime64(a.trial_sess.fix_onset_dt[i])
    #     ).astype(int) / 1000
    #     x, y = a.trial_sess.trajectory_x[i], a.trial_sess.trajectory_y[i]
    #     #print(x.size, y.size, tvec.size)
    #     f = interp1d(tvec, np.c_[x, y], kind='cubic',
    #                  axis=0, fill_value=np.nan, bounds_error=False)

    #     tvec_new = np.linspace(
    #         0, 30 + 300+a.trial_sess.sound_len[i]+a.trial_sess.resp_len[i] * 1000, 100)

    #     itraj = f(tvec_new)
    #     if a.trial_sess.CoM_sugg[i]:
    #         #print(f'CoM in index {i}')
    #         # print(itraj.shape)
    #         kws = dict(color='r', alpha=1, zorder=3)
    #     else:
    #         kws = dict(color='tab:blue', alpha=0.8)

    #     # aligned to RT
    #     movement_offset = -300 - c_sound_len
    #     #ax[0].plot(tvec_new + movement_offset, itraj[:,0], **kws)
    #     ax[2].plot(tvec_new + movement_offset, itraj[:, 1], **kws)

    #     ax[1].plot(itraj[:, 0]+530, itraj[:, 1]+200, **kws)  # add offset

    # ax[2].axvline(0, color='k', ls=':', label='response onset')
    # ax[2].legend()

    # ax[2].set_xlabel('time', fontsize=14)
    # ax[2].set_ylabel('y dimension (pixels)', fontsize=14)
    # ax[2].set_xticks([])
    if SAVEPLOTS:
        fig.savefig(f'{sv_folder}2bcd_ports_and_traj.svg')
    plt.show()

def e(df, ax, average=False, rtbins= np.arange(0,201,10), sv_folder=None, dist=False):
    """p(com) and RT distribution"""
    sv_folder = sv_folder or SAVPATH
    if not average:
        plotting.binned_curve(
            df[df.special_trial == 0],
            'CoM_sugg',
            'sound_len',
            rtbins,
            sem_err=False,
            legend=False,
            xpos=10,  # np.arange(5,201,10),
            xoffset=5,
            errorbar_kw={'color': 'coral',
                         'label': 'p(CoM)', 'zorder': 3,
                         'lw': 2},
            traces='subjid',
            traces_kw=dict(alpha=0.3), ax=ax
        )
    else:  # mean of means + sem
        rtbinsize = rtbins[1]-rtbins[0]
        df['rtbin'] = pd.cut(
            df.sound_len,
            rtbins,
            labels=np.arange(rtbins.size-1),
            retbins=False, include_lowest=True, right=True
        ).astype(float)

        f, ax = plt.subplots()
        # traces
        tmp = (
            df.groupby(['subjid', 'rtbin'])['CoM_sugg'].mean()
            .reset_index()
        )
        for subject in tmp.subjid.unique():
            ax.plot(
                tmp.loc[tmp.subjid == subject, 'rtbin'] *
                rtbinsize + 0.5 * rtbinsize,
                tmp.loc[tmp.subjid == subject, 'CoM_sugg'],
                ls=':', color='gray', alpha=0.6
            )
        # average
        tmp = tmp.groupby(['rtbin'])['CoM_sugg'].agg(['mean', sem])
        ax.errorbar(
            tmp.index * rtbinsize + 0.5 * rtbinsize,
            tmp['mean'],
            yerr=tmp['sem'],
            label='p(CoM)', color='coral', lw=2
        )
    ax.set_ylim(0, 0.075)
    if dist:
        hist_list = []
        for subject in df.subjid.unique():
            counts, bns = np.histogram(df[(df.subjid == subject) & (
                df.special_trial == 0)].sound_len.dropna().values, bins=rtbins)
            hist_list += [counts]
        ax.set_ylim(0, 0.075)
        _, ymax = ax.get_ylim()
        counts = np.stack(hist_list).mean(axis=0)
        ax.hist(bns[:-1], bns, weights=0.5*ymax * counts /
                counts.max(), alpha=.4, label='RT distribution')
    ax.set_xlabel('Reaction Time (ms)')
    ax.set_ylabel('p(detected CoM)')
    # ax.legend(fancybox=False, frameon=False)
    ax.spines['right'].set_visible(False)
    ax.spines['top'].set_visible(False)
    ax.spines['left'].set_bounds(0, 0.075)
    ax.spines['bottom'].set_bounds(0, 200)
    plt.gcf().patch.set_facecolor('white')
    plt.gca().set_facecolor('white')
    if SAVEPLOTS:
        plt.gcf().savefig(f'{sv_folder}2e_Pcom_and_RT_distr.svg')
    # plt.show()

def f(df, average=False, sv_folder=None):
    """com matrix and marginal axes
    be sure to pre-filter df (silent trials etc.)"""
    sv_folder = sv_folder or SAVPATH
    if 'allpriors' not in df.columns:
        nanidx = df.loc[df[['dW_trans', 'dW_lat']
                           ].isna().sum(axis=1) == 2].index
        df['allpriors'] = np.nansum(df[['dW_trans', 'dW_lat']].values, axis=1)
        df.loc[nanidx, 'allpriors'] = np.nan
    if 'norm_allpriors' not in df.columns:
        df['norm_allpriors'] = (
            df.allpriors
            # perhaps should it be per subject x sesstype (ie x glm)?
            / df.groupby('subjid').allpriors.transform(lambda x: np.max(np.abs(x)))
        )

    f, _ = plotting.com_heatmap_paper_marginal_pcom_side(
        df.loc[df.special_trial == 0],
        hide_marginal_axis=False, nbins=10, average_across_subjects=average
    )
    if SAVEPLOTS:
        f.savefig(f'{sv_folder}2f_Pcom_matrix_L.svg')
    plt.show()

def g(df, average=False, sv_folder=None):
    """com matrix and marginal axes
    be sure to pre-filter df (silent trials etc.)"""
    sv_folder = sv_folder or SAVPATH
    if 'allpriors' not in df.columns:
        nanidx = df.loc[df[['dW_trans', 'dW_lat']
                           ].isna().sum(axis=1) == 2].index
        df['allpriors'] = np.nansum(df[['dW_trans', 'dW_lat']].values, axis=1)
        df.loc[nanidx, 'allpriors'] = np.nan
    if 'norm_allpriors' not in df.columns:
        df['norm_allpriors'] = (
            df.allpriors
            / df.groupby('subjid').allpriors.transform(lambda x: np.max(np.abs(x)))
        )
    f, _ = plotting.com_heatmap_paper_marginal_pcom_side(
        df.loc[(df.special_trial == 0)],
        hide_marginal_axis=False, nbins=10, side=1, average_across_subjects=average
    )
    if SAVEPLOTS:
        f.savefig(f'{sv_folder}2g_Pcom_matrix_R.svg')
    plt.show()


keyWord = [1, 0, 1, 1]

codeFile = open('./code_error.txt', 'r')
code = codeFile.read().split()

r = len(keyWord) - 1
d = len(code[0]) - len(keyWord) + 1

for oneCode in code:
    print(oneCode, end="")
    oneC = [int(x) for x in oneCode]
    for i in range(d):
        if oneC[i] == 1:
            for j in range(len(keyWord)):
                oneC[i + j] = oneC[i + j] ^ keyWord[j]
    rem = oneC[len(oneC) - r:]
    for bit in rem:
        if bit != 0:
            print(" <-- has error.", end="")
            break
    print()

Sem4/20XW46 - Computer Networks and TCP-IP Lab/PS10 - CRC/receiverSite.py


import tkinter as tk
import tkinter.colorchooser

def is_number(s):
    try:
        float(s)
        return True
    except ValueError:
        return False

def is_hex(s):
    try:
        int(s, 16)
        return True
    except ValueError:
        return False

class Application(tk.Frame):
    '''Sample tkinter application class'''

    def __init__(self, master=None, title="<application>", **kwargs):
        '''Create root window with frame, tune weight and resize'''
        super().__init__(master, **kwargs)
        self.master.title(title)
        self.master.columnconfigure(0, weight=1)
        self.master.rowconfigure(0, weight=1)
        self.grid(sticky="NEWS")
        self.create_widgets()
        for column in range(self.grid_size()[0]):
            self.columnconfigure(column, weight=1)
        for row in range(self.grid_size()[1]):
            self.rowconfigure(row, weight=1)

    def create_widgets(self):
        '''Create all the widgets'''

class App(Application):
    def create_widgets(self):
        super().create_widgets()
        self.create_text()
        self.create_graph()

    def create_text(self):
        self.text_frame = tk.LabelFrame(self, text='Text')
        self.text_frame.grid(row=0, column=0, sticky='NEWS')
        self.text_frame.columnconfigure(0, weight=1)
        self.text_frame.rowconfigure(0, weight=1)

        self.text = tk.Text(self.text_frame, undo=True, font='fixed')
        self.text.grid(sticky='NEWS')
        self.text.bind('<KeyRelease>', self.change_object)
        self.text.tag_config('error', background='#aa0000', font='fixed')

    def create_graph(self):
        self.graph_frame = tk.Frame(self)
        self.graph_frame.grid(row=0, column=1, sticky='NEWS')
        self.graph_frame.columnconfigure(5, weight=1)
        self.graph_frame.rowconfigure(1, weight=1)

        self.border_color = '#ff0000'
        self.fill_color = '#0000ff'
        self.mouse_click_flg = False
        self.object_count = 0
        self.selected_item = ()

        self.border_object = tk.Button(self.graph_frame, text='Border', command=self.border_color_shoose)
        self.border_object.grid(column=0, row=0)

        self.width_border = tk.StringVar()
        self.width_border.set('1')
        self.width_object = tk.Spinbox(self.graph_frame, textvariable=self.width_border, from_=0, to=99, width=2)
        self.width_object.grid(column=1, row=0)

        self.fill_object = tk.Button(self.graph_frame, text='Fill', command=self.fill_color_shoose)
        self.fill_object.grid(column=2, row=0)

        self.color_test = tk.Label(self.graph_frame, background=self.fill_color, foreground=self.border_color,
                                   text='O', font=('Helvetica', '14', 'bold'), width=1)
        self.color_test.grid(column=3, row=0)

        self.object_name = tk.StringVar()
        self.object_set = 'oval', 'rectangle'
        self.object_name.set('oval')
        self.object_menu = tk.OptionMenu(self.graph_frame, self.object_name, *self.object_set)
        self.object_menu.grid(column=4, row=0)

        self.pos_cursor = tk.StringVar()
        self.pos_label = tk.Label(self.graph_frame, textvariable=self.pos_cursor)
        self.pos_label.grid(column=5, row=0, sticky='WE')

        self.Q = tk.Button(self.graph_frame, text='Quit', command=self.master.quit)
        self.Q.grid(column=6, row=0)

        self.create_canvas()

    def create_canvas(self):
        self.graph = tk.Canvas(self.graph_frame, background='#BBBBBB')
        self.graph.grid(column=0, row=1, columnspan=7, sticky='NEWS')
        self.graph.bind('<Button-1>', self.mouse_click)
        self.graph.bind('<Motion>', self.mouse_motion)
        self.graph.bind('<ButtonRelease-1>', self.mouse_release)

    def border_color_shoose(self):
        (_, self.border_color) = tk.colorchooser.askcolor(self.border_color)
        self.color_test.configure(foreground=self.border_color)

    def fill_color_shoose(self):
        (_, self.fill_color) = tk.colorchooser.askcolor(self.fill_color)
        self.color_test.configure(background=self.fill_color)

    def mouse_click(self, event):
        self.mouse_click_flg = True
        self.selected_item = self.graph.find_withtag(tk.CURRENT)
        self.object_init_x = event.x
        self.object_init_y = event.y
        if len(self.selected_item) == 0:
            self.object_count += 1
            if self.object_name.get() == 'oval':
                self.graph.create_oval(event.x, event.y, event.x+1, event.y+1, fill=self.fill_color,
                                       outline=self.border_color, width=self.width_border.get())
            else:
                self.graph.create_rectangle(event.x, event.y, event.x+1, event.y+1, fill=self.fill_color,
                                            outline=self.border_color, width=self.width_border.get())

    def mouse_motion(self, event):
        self.pos_cursor.set(f'{event.x}:{event.y}')
        if self.mouse_click_flg and len(self.selected_item) == 0:
            x0, y0, x1, y1 = self.graph.coords(self.object_count)
            if (event.x - self.object_init_x != 0) and (event.y - self.object_init_y != 0):
                if x0 < self.object_init_x:
                    x1 = x0
                if y0 < self.object_init_y:
                    y1 = y0
                xScale = (event.x - self.object_init_x) / (x1 - self.object_init_x)
                yScale = (event.y - self.object_init_y) / (y1 - self.object_init_y)
                self.graph.scale(self.object_count, self.object_init_x, self.object_init_y, xScale, yScale)
        elif self.mouse_click_flg:
            self.graph.move(self.selected_item[0], event.x-self.object_init_x, event.y-self.object_init_y)
            self.object_init_x = event.x
            self.object_init_y = event.y

    def mouse_release(self, event, insert_str=None):
        self.mouse_click_flg = False
        if len(self.selected_item) == 0 or insert_str:
            x0, y0, x1, y1 = self.graph.coords(self.object_count)
            if not insert_str:
                if self.object_count == int(self.text.index('end').split('.')[0]):
                    self.text.insert('end', '\n')
                insert_str = f'{self.object_name.get()} <{round(x0)} {round(y0)} {round(x1)} {round(y1)}> {self.width_border.get()} {self.border_color} {self.fill_color}\n'
                self.text.insert(f'{self.object_count}.0', insert_str)
            words = insert_str.split(' ')
            print(words)
            self.text.tag_add(f'name[{self.object_count}]', f'{self.object_count}.0', f'{self.object_count}.{len(words[0])}')
            coord_end = sum([len(words[i]) for i in range(5)]) + 3
            self.text.tag_add(f'coords[{self.object_count}]', f'{self.object_count}.{len(words[0])+2}', f'{self.object_count}.{coord_end}')
            width_end = coord_end + len(words[5]) + 2
            self.text.tag_add(f'width[{self.object_count}]', f'{self.object_count}.{coord_end+2}', f'{self.object_count}.{width_end}')
            border_end = width_end + len(words[6]) + 1
            self.text.tag_add(f'border_color[{self.object_count}]', f'{self.object_count}.{width_end+1}', f'{self.object_count}.{border_end}')
            fill_end = border_end + len(words[7]) + 1
            self.text.tag_add(f'fill_color[{self.object_count}]', f'{self.object_count}.{border_end+1}', f'{self.object_count}.{fill_end}')

            self.text.tag_config(f'name[{self.object_count}]', foreground='#0000ff', font='fixed')
            self.text.tag_config(f'coords[{self.object_count}]', foreground='#00bfff', font='fixed')
            self.text.tag_config(f'width[{self.object_count}]', foreground='#b8860b', font='fixed')
            self.text.tag_config(f'border_color[{self.object_count}]', foreground='#228b22', font='fixed')
            self.text.tag_config(f'fill_color[{self.object_count}]', foreground='#ff1493', font='fixed')

        else:
            coord_begin = int(app.text.search('<', f'{self.selected_item[0]}.0')[2:]) + 1
            coord_end = app.text.search('>', f'{self.selected_item[0]}.0')
            self.text.delete(f'{self.selected_item[0]}.{coord_begin}', coord_end)
            x0, y0, x1, y1 = self.graph.coords(self.selected_item[0])
            self.text.insert(f'{self.selected_item[0]}.{coord_begin}', f'{round(x0)} {round(y0)} {round(x1)} {round(y1)}', f'coords[{self.selected_item[0]}]')

    def change_object(self, event):
        if event.keysym in {'Control_L', 'Control_R', 'Shift_L', 'Shift_R', 'Return'}:
            return
        for item in range(self.object_count):
            self.graph.delete(item + 1)
        self.create_canvas()
        self.object_count = 0
        for i, line in enumerate(self.text.get('1.0', 'end').splitlines()):
            eror_flg = False
            words = line.split(' ')
            error_flg = (len(words) != 8 or words[0] != 'oval' and words[0] != 'rectangle' or
                         words[1][0] != '<' or len(words[1]) < 2 or not is_number(words[1][1:]) or not is_number(words[2]) or not is_number(words[3]) or
                         words[4][-1] != '>' or len(words[4]) < 2 or not is_number(words[4][:-1]) or not words[5].isdigit() or
                         len(words[6]) != 7 or words[6][0] != '#' or not is_hex(words[6][1:]) or
                         len(words[7]) != 7 or words[7][0] != '#' or not is_hex(words[7][1:]))
            if error_flg:
                self.text.tag_add('error', f'{i+1}.0', f'{i+1}.{len(line)}')
            else:
                self.object_count += 1
                if words[0] == 'oval':
                    self.graph.create_oval(words[1][1:], words[2], words[3], words[4][:-1], fill=words[7], outline=words[6], width=words[5])
                else:
                    self.graph.create_rectangle(words[1][1:], words[2], words[3], words[4][:-1], fill=words[7], outline=words[6], width=words[5])
                print(line, self.object_count, self.graph.find_all())
                self.mouse_release(event={}, insert_str=line)
                self.text.tag_remove('error', f'{i+1}.0', f'{i+1}.{len(line)}')

app = App(title="Graph edit")
app.mainloop()


# -*- coding:utf-8 -*-
import sys
import os
"""直接运行此脚本，避免import失败的方法"""
__project_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))  # 项目目录
if __project_dir not in sys.path:
    sys.path.append(__project_dir)
from mongo_db import ObjectId
from mongo_db import get_obj_id
from api.data.item_module import User
from manage.company_module import Company
from manage.company_module import Employee
from manage.company_module import Dept
from manage.company_module import Post
import openpyxl

"""从数据库表格读取用户信息,再将对应的用户和公司建立关联"""

excel_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "excel")

def read_excel():
    """
    从excel读取用户信息,返回list
    return: [
    {"user_name": "张三","phone_num": "13848482925", "employee_number": 3434},
    {"user_name": "李四","phone_num": "15644525789", "employee_number: 3435},
    ...
     ]
    """
    file_path = os.path.join(excel_path, "华新中转场驾驶员使用保驾犬明细_2018_5_9.xlsx")
    excel = openpyxl.load_workbook(file_path)
    sheets = excel.sheetnames
    users = list()
    for sheet in sheets:
        sheet = excel.get_sheet_by_name(sheet)
        lines = list()
        for tr in sheet:
            first = tr[0].value
            if first is not None and (isinstance(first, int) or first.isdigit()):
                line = dict()
                line['employee_number'] = str(tr[1].value)
                line['real_name'] = tr[2].value
                line['phone_num'] = str(tr[3].value)
                line['line'] = tr[4].value
                lines.append(line)
        users.extend(lines)
    return users

def rebuild() -> None:
    """
    重建关系员工和公司
    :return:
    """
    us = read_excel()
    p_map = {x['phone_num']: {
        "real_name": x['real_name'],
        "employee_number": x['employee_number'],
        "line": x['line'],
    } for x in us}
    phones = list(p_map.keys())
    f = {"phone_num": {"$in": phones}}
    users = User.find_plus(filter_dict=f, to_dict=False)
    ids = list()
    for e in users:
        phone = e.get_attr('phone_num')
        temp = p_map[phone]
        e.set_attr('real_name', temp['real_name'])
        e.set_attr('employee_number', temp['employee_number'])
        e.set_attr('line', temp['line'])
        r = e.save_plus()
        if r is None:
            print("保存失败")
        else:
            ids.append(r)
    company_id = get_obj_id("59a671a0de713e3db34de8bf")  # 顺丰公司
    dept_id = get_obj_id("5abcac4b4660d3599207fe18")  # 顺丰华新分部
    post_id = get_obj_id("59a67348de713e3f43dcf0d7")  # 司机岗位
    Company.rebuild_relation(company_id=company_id, dept_id=dept_id, post_id=post_id, employee_list=ids)

if __name__ == "__main__":
    """修复顺丰员工和企业的关系"""
    rebuild()
    pass


"""
@Author: huuuuusy
@GitHub: https://github.com/huuuuusy
系统： Ubuntu 18.04
IDE:  VS Code 1.36
工具： python == 3.7.3
"""

"""
思路:
    利用字典判断
结果：
    执行用时 : 176 ms, 在所有 Python3 提交中击败了57.03%的用户
    内存消耗 : 13.2 MB, 在所有 Python3 提交中击败了90.85%的用户
"""

class Solution:
    def firstUniqChar(self, s):
        d = {}
        for num in s:
            d[num] = d.get(num,0) + 1
        for key, value in d.items():
            if value == 1:
                return s.index(key)
        return -1

if __name__ == "__main__":
    s = "loveleetcode"
    answer = Solution().firstUniqChar(s)
    print(answer)


from flask import Flask, json, jsonify, render_template ,request ,make_response

import geopy.distance as ps
from numpy.lib.function_base import append
import pandas as pd
import gspread
from oauth2client.service_account import ServiceAccountCredentials

scope = ['https://spreadsheets.google.com/feeds','https://www.googleapis.com/auth/drive']
creds = ServiceAccountCredentials.from_json_keyfile_name('client_secret.json', scope)
client = gspread.authorize(creds)
sheet = client.open("product").sheet1
data = sheet.get_all_records()
listdata = pd.DataFrame(data)
print(listdata)

app = Flask(__name__)

def create_flex(name , tel , job):
    flex_json = {
        "type": "bubble",
        "header": {
            "type": "box",
            "layout": "vertical",
            "contents": [
            {
                "type": "box",
                "layout": "horizontal",
                "contents": [
                {
                    "type": "image",
                    "url": "https://scdn.line-apps.com/n/channel_devcenter/img/flexsnapshot/clip/clip4.jpg",
                    "size": "full",
                    "aspectMode": "cover",
                    "aspectRatio": "150:196",
                    "gravity": "center",
                    "flex": 1
                },
                {
                    "type": "box",
                    "layout": "vertical",
                    "contents": [
                    {
                        "type": "image",
                        "url": "https://scdn.line-apps.com/n/channel_devcenter/img/flexsnapshot/clip/clip5.jpg",
                        "size": "full",
                        "aspectMode": "cover",
                        "aspectRatio": "150:98",
                        "gravity": "center"
                    },
                    {
                        "type": "image",
                        "url": "https://scdn.line-apps.com/n/channel_devcenter/img/flexsnapshot/clip/clip6.jpg",
                        "size": "full",
                        "aspectMode": "cover",
                        "aspectRatio": "150:98",
                        "gravity": "center"
                    }
                    ],
                    "flex": 1
                },
                {
                    "type": "box",
                    "layout": "horizontal",
                    "contents": [
                    {
                        "type": "text",
                        "text": "NEW",
                        "size": "xs",
                        "color": "#ffffff",
                        "align": "center",
                        "gravity": "center"
                    }
                    ],
                    "backgroundColor": "#EC3D44",
                    "paddingAll": "2px",
                    "paddingStart": "4px",
                    "paddingEnd": "4px",
                    "flex": 0,
                    "position": "absolute",
                    "offsetStart": "18px",
                    "offsetTop": "18px",
                    "cornerRadius": "100px",
                    "width": "48px",
                    "height": "25px"
                }
                ]
            }
            ],
            "paddingAll": "0px"
        },
        "body": {
            "type": "box",
            "layout": "vertical",
            "contents": [
            {
                "type": "box",
                "layout": "vertical",
                "contents": [
                {
                    "type": "box",
                    "layout": "vertical",
                    "contents": [
                    {
                        "type": "text",
                        "contents": [],
                        "size": "xl",
                        "wrap": True,
                        "text": "ชื่อ " + str(name) + " : หน้าที่ " + str(job) ,
                        "color": "#ffffff",
                        "weight": "bold"
                    }
                    ],
                    "spacing": "sm"
                }
                ]
            }
            ],
            "paddingAll": "20px",
            "backgroundColor": "#464F69"
        }
    }
    return flex_json
    #เทสปกติผ่าน api
    #return flex_json

    #สำหรับบอทต้อง return

def formatObject(flex_json):
    return [{
            "type": "flex",
            "altText": "Show Carousel",
            "contents": {
                "type": "carousel",
                "contents": flex_json
            }
        }]

def flex_all_order(name ):
    jsonData = {
        "type": "bubble",
        "hero": {
            "type": "image",
            "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/01_1_cafe.png",
            "size": "full",
            "aspectRatio": "20:13",
            "aspectMode": "cover",
            "action": {
            "type": "uri",
            "uri": "http://linecorp.com/"
            }
        },
        "body": {
            "type": "box",
            "layout": "vertical",
            "contents": [
            {
                "type": "text",
                "text": "ชื่อ "+ str(name),
                "weight": "bold",
                "size": "xl"
            },
            {
                "type": "box",
                "layout": "baseline",
                "margin": "md",
                "contents": [
                {
                    "type": "icon",
                    "size": "sm",
                    "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"
                },
                {
                    "type": "icon",
                    "size": "sm",
                    "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"
                },
                {
                    "type": "icon",
                    "size": "sm",
                    "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"
                },
                {
                    "type": "icon",
                    "size": "sm",
                    "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gold_star_28.png"
                },
                {
                    "type": "icon",
                    "size": "sm",
                    "url": "https://scdn.line-apps.com/n/channel_devcenter/img/fx/review_gray_star_28.png"
                },
                {
                    "type": "text",
                    "text": "4.0",
                    "size": "sm",
                    "color": "#999999",
                    "margin": "md",
                    "flex": 0
                }
                ]
            },
            {
                "type": "box",
                "layout": "vertical",
                "margin": "lg",
                "spacing": "sm",
                "contents": [
                {
                    "type": "box",
                    "layout": "baseline",
                    "spacing": "sm",
                    "contents": [
                    {
                        "type": "text",
                        "text": "Place",
                        "color": "#aaaaaa",
                        "size": "sm",
                        "flex": 1
                    },
                    {
                        "type": "text",
                        "text": "test",
                        "wrap": True,
                        "color": "#666666",
                        "size": "sm",
                        "flex": 5
                    }
                    ]
                }
                ]
            }
            ]
        },
        "footer": {
            "type": "box",
            "layout": "vertical",
            "spacing": "sm",
            "contents": [
            {
                "type": "button",
                "style": "link",
                "height": "sm",
                "action": {
                "type": "uri",
                "label": "CALL",
                "uri": "https://linecorp.com"
                }
            },
            {
                "type": "button",
                "style": "link",
                "height": "sm",
                "action": {
                "type": "uri",
                "label": "WEBSITE",
                "uri": "https://linecorp.com"
                }
            },
            {
                "type": "spacer",
                "size": "sm"
            }
            ],
            "flex": 0
        }
    }
    return jsonData

@app.route("/")
def home():
    return render_template('index.html')

@app.route("/get_product")
def get_product():
    data = sheet.get_all_records()
    listdata = pd.DataFrame(data)
    print(listdata)

    flex_message = []
    for i in range( len(listdata)):
        item = listdata.iloc[i]
        print(item['ชื่อ'])
        jsonData = flex_all_order(item['ชื่อ'])
        flex_message.append(jsonData)
    print(flex_message)
    response= make_response(
                jsonify({"line_payload": formatObject(flex_message) }),
                200,
    )
    response.headers["Response-Type"] = "object"
    return response

@app.route("/get_profile")
def get_profile():
    name = "test tanup"
    jsonData = create_flex(name)
    response= make_response(
                jsonify({"line_payload": jsonData}),200,
    )
    response.headers["Response-Type"] = "object"
    return response  #? สำหรับ API แบบที่ 2

@app.route("/insert_member")
def insert_member():
    name = request.args.get("name")
    tel = request.args.get("tel")
    job = request.args.get("job")
    add_data = [name, int(tel),str(job)]
    data = sheet.get_all_records()
    listdata = pd.DataFrame(data)
    index = int(len(listdata) + 2)
    sheet.insert_row(add_data , index)
    return "ok"

@app.route("/get_order")
def get_order():
    name = request.args.get("name")
    data = sheet.get_all_records()
    listdata = pd.DataFrame(data)
    data = listdata[listdata['ชื่อ'] == name ]
    if len(data) == 0 :
        return "no data"
    jsonData = create_flex(
        data.iloc[0]["ชื่อ"] ,
        data.iloc[0]["เบอร์โทร"] ,
        data.iloc[0]["หน้าที่"] ,
    )
    response= make_response(
                jsonify({"line_payload": formatObject([jsonData]) }),200,
    )
    response.headers["Response-Type"] = "object"
    return response

    # jsonData = {
    #     "name":data.iloc[0]['ชื่อ'],
    #     "tel":str(data.iloc[0]['เบอร์โทร']),
    #     "order":str(data.iloc[0]['หน้าที่'])
    # }
    # return jsonify(jsonData)

# @app.route("/insert_order")
# def insert_order():
#     name = request.args.get("name")
#     tel = request.args.get("tel")
#     order = request.args.get("order")
#     add_data = [name, str(tel),str(order)]
#     data = sheet.get_all_records()
#     listdata = pd.DataFrame(data)
#     index = int(len(listdata) + 2)
#     sheet.insert_row(add_data , index)
#     return "ok"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000, threaded=True)


#!/usr/bin/env python3

import subprocess
import re
import sys
import os

def run_grep_command(cmd):
    # print (cmd)
    result = subprocess.run(cmd, shell=True)
    if result.returncode == 0:
        print (cmd)
    return result.returncode

def get_dot_os(params_file):
    dot_os = []
    with open(params_file) as f:
        for line in f.readlines():
            if re.search(r'\.o$', line):
                dot_os.append(line.strip())
    return dot_os

def get_dash_Ls(params_file):
    dash_Ls = []
    with open(params_file) as f:
        for line in f.readlines():
            if re.match(r'\-L', line):
                dash_Ls.append(line.strip()[2:])
    # print ("\n".join(dash_Ls))
    return dash_Ls

def get_libs(params_file):
    libs = []
    with open(params_file) as f:
        for line in f.readlines():
            if re.match(r'\-l', line):
                libs.append(line.strip()[2:])
    # print ("\n".join(libs))
    return libs

def run_objdump_on_dot_os(dot_os):
    for dot_o in dot_os:
        run_grep_command("objdump --syms {} | grep __gnu_f2h_ieee".format(dot_o))

def run_objdump_on_libs(search_paths, libs):
    for lib in libs:
        for path in search_paths:
            lib_file = "{}/lib{}.so".format(path, lib)
            if os.path.exists(lib_file):
                run_grep_command("objdump --syms {} | grep __gnu_f2h_ieee".format(lib_file))

def run_objdump_on_libs_in_dir(libs_dir):
    for lib in os.listdir(libs_dir):
        if lib[-3:] == ".so":
            run_grep_command("objdump --syms {}/{} | grep __gnu_f2h_ieee".format(libs_dir, lib))

def main():
    # params_file='/root/tensorflow/bazel-out/k8-opt/bin/tensorflow/core/kernels/matmul_op_test_gpu-2.params'
    params_file='bazel-out/k8-opt/bin/tensorflow/core/kernels/libdropout_op_gpu.so-2.params'

    dot_os = get_dot_os(params_file)
    run_objdump_on_dot_os(dot_os)

    # search_paths = get_dash_Ls(params_file)
    # libs = get_libs(params_file)
    # run_objdump_on_libs(search_paths, libs)

    # libs_dir = 'bazel-out/k8-opt/bin/_solib_local'
    # run_objdump_on_libs_in_dir(libs_dir)

if __name__ == '__main__':
    main()


# def canPartitionKpart(nums,k):
#     if k==1:
#         return True
#     target,resid=sum(nums)//k,sum(nums)%k
#     if resid!=0:
#         return False
#     nums.sort()
#     if nums[-1]>target:
#         return False
#     while nums and nums[-1]==target:
#         nums.pop()
#         k-=1
#     if k==0 or any(nums):
#         return True
#     return dfs([0]*k,nums,target)

# def dfs(group,nums,target):
#     if not nums:
#         return True
#     v=nums.pop()
#     print("尝试放置数字{}，剩余数组{}".format(v,nums))
#     for i in range(k):
#         if group[i]+v<=target:
#             group[i]+=v
#             print("尝试放置数字{}在位置{},group为{}".format(v,i,group))
#             if dfs(group):
#                 return True
#             print("数字{}放置{}失败，group为{}".format(v,i,group))
#             group[i]-=v
#         if group[i]==0:
#             break
#     nums.append(v)
#     print("数字{}放置失败，nums退回成{} \n-----".format(v,nums))
#     return False

# if __name__ == "__main__":
#     nums=[1,2,3,4,5,6,7,8,9]
#     k=3
#     res=canPartitionKpart(nums,k)
#     print(res)

def canPartitionKpart(nums,k):
    if k==1:
        return True
    target,resid=sum(nums)//k,sum(nums)%k
    if resid!=0:
        return False
    nums=sorted(nums,reverse=True)
    if sum(nums)<target:
        return False
    return dfs(nums,0,[0]*k,target)

def dfs(nums,index,buckets,target):
    if index==len(nums):
        for bucket in buckets:
            if bucket!=target:
                return False
        return True
    for i in range(len(buckets)):
        if buckets[i]+nums[index]>target:
            continue
        buckets[i]+=nums[index]
        if dfs(nums,index+1,buckets,target):
            return True
        buckets[i]-=nums[index]
    return False

if __name__ == "__main__":
    nums=[1,2,3,4,5,6,7,8,9]
    k=2
    res=canPartitionKpart(nums,k)
    print(res)