def standup_active(token, channel_id): # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # check channel_id is valid db_connect = DbConnector() db_connect.cursor() sql = "SELECT channel_id FROM project.channel_data WHERE channel_id=(%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret is None: raise InputError( description='error occurred: Channel ID is not a valid channel') # delete finished standup curr_time = int(time.time()) # check if standup is active sql = "SELECT time_finish FROM project.active_data WHERE channel_id=(%s);" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret is not None: time_finish = ret[0] if int(time_finish) > curr_time: db_connect.close() return {'is_active': True, 'time_finish': time_finish} # close database connection db_connect.close() return {'is_active': False, 'time_finish': None}
def user_profile_sethandle(token, handle_str): # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') if len(handle_str) > 20 or len(handle_str) < 3: # check handle is valid raise InputError( description= 'error occurred: handle must be between 3 and 20 characters') db_connect = DbConnector() db_connect.cursor() sql = "SELECT handle FROM project.user_data WHERE handle=(%s)" value = (handle_str, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret is not None: raise InputError( description='error occurred: handle is already used by another user' ) # get user's u_id from token token_operation = TokenJwt() u_id = token_operation.get_uid(token) sql = "UPDATE project.user_data SET handle=(%s) WHERE u_id=(%s);" value = (handle_str, u_id) db_connect.execute(sql, value) # close database connection db_connect.close() return {}
def channels_create(token: str, name: str, is_public: bool) -> dict: """ Creates a new channel with that name that is either a public or private channel :param token: user's token :param name: channel's name :param is_public: boolean expression of whether the channel is public or private :return: the dictionary with key 'channel_id' """ token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') if len(name) > 20: raise InputError( description='error occurred: Name is more than 20 characters long') u_id = token_operation.get_uid(token) # db_connect = DbConnector() db_connect.cursor() sql = "INSERT INTO project.channel_data(name, member, owner,is_public) VALUES (%s,%s, %s, %s);" value = (name, [u_id], [u_id], is_public) db_connect.execute(sql, value) # get the channel_id sql = "SELECT MAX(channel_id) FROM project.channel_data" db_connect.execute(sql) ret = db_connect.fetchone() channel_id = ret[0] return { 'channel_id': channel_id, }
def channels_listall(token: str) -> dict: """ Provide a list of all channels (and their associated details) :param token: user's token :return: dictionary of list of dictionary with keys 'channel_id' and 'name' which includes all the channels """ #token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') dictionary = { 'channels': [], } # get info for all list db_connect = DbConnector() db_connect.cursor() sql = "SELECT channel_id, name FROM project.channel_data" db_connect.execute(sql) ret = db_connect.fetchall() for channel in ret: dictionary['channels'].append({ 'channel_id': channel[0], 'name': channel[1] }) # close database connection db_connect.close() return dictionary
def user_profile_setname(token, name_first, name_last): # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') if len(name_first) > 50 or len( name_first) < 1: # check length of name_first raise InputError( description='error occurred: first name is not between \ 1 and 50 characters inclusively in length') if len(name_last) > 50 or len(name_last) < 1: raise InputError( description='error occurred: last name is not between \ 1 and 50 characters inclusively in length') # get user's u_id from token token_operation = TokenJwt() u_id = token_operation.get_uid(token) db_connect = DbConnector() db_connect.cursor() sql = "UPDATE project.user_data SET name_first=(%s), \ name_last=(%s) WHERE u_id=(%s)" value = (name_first, name_last, u_id) db_connect.execute(sql, value) db_connect.close() return {}
def channel_addowner(token: str, channel_id: int, u_id: int) -> dict: """ Make user with user id u_id an owner of this channel :param token: user's token :param channel_id: channel's id :param u_id: user's id :return: an empty dictionary """ # check token_operation = TokenJwt() if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # get authorised user's u_id from token authorised_uid = token_operation.get_uid(token) db_connect = DbConnector() db_connect.cursor() sql = "SELECT member, owner FROM project.channel_data WHERE channel_id=(%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() # check channel is valid if ret is None: raise InputError(description='error occurred: Channel ID is not valid') member_list = ret[0] owner_list = ret[1] # user is already owner if u_id in owner_list: raise InputError( description= 'error occurred: user is already an owner of the channel') # check authorised_uid is valid if authorised_uid not in owner_list: raise AccessError( description= 'error occurred: the authorised user is not an owner of the flockr, ' 'or an owner of this channel') # update database sql = "UPDATE project.channel_data SET member=(%s), owner=(%s) WHERE channel_id=(%s)" owner_list.append(u_id) if u_id not in member_list: member_list.append(u_id) value = (member_list, owner_list, channel_id) db_connect.execute(sql, value) # close database connection db_connect.close() return {}
def user_profile_uploadphoto(token, img_url, x_start, y_start, x_end, y_end): token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') try: urllib.request.urlopen(img_url) except urllib.error.HTTPError: raise InputError(description='error occurred: \ img_url returns an HTTP status other than 200.') # check img is jpg if not img_url.lower().endswith('.jpg'): raise InputError( description='error occurred: Image uploaded is not a JPG') if not os.path.exists('./image'): os.makedirs('./image') # get user's u_id from token u_id = token_operation.get_uid(token) image_address = './image/' + str(u_id) + '.jpg' urllib.request.urlretrieve(img_url, image_address) image_object = Image.open(image_address) width, height = image_object.size if (int(x_start) < 0 or int(x_start) > width or int(x_end) < 0 or int(x_end) > width or int(y_start) < 0 or int(y_start) > height or int(y_end) < 0 or int(y_end) > height): os.remove(image_address) raise InputError(description="x_start, y_start, x_end, y_end are not \ within the dimensions of the image at the URL") if int(x_start) >= int(x_end) or int(y_start) >= int(y_end): os.remove(image_address) raise InputError(description="start value can't exceed end value") cropped = image_object.crop((x_start, y_start, x_end, y_end)) cropped.save(image_address) base_url = flask.request.host_url image_url = base_url + 'image/' + str(u_id) + '.jpg' db_connect = DbConnector() db_connect.cursor() sql = "UPDATE project.user_data SET profile_img_url=(%s) WHERE u_id=(%s)" value = (image_url, u_id) db_connect.execute(sql, value) # close database connection db_connect.close() return {}
def channel_join(token: str, channel_id: int) -> dict: """ :param token: :param channel_id: :return: """ # check token is valid token_operation = TokenJwt() if check_valid(token) is False: raise AccessError(description='error occured: token is not valid') # get user's u_id from token u_id = token_operation.get_uid(token) if not isinstance(channel_id, int): raise InputError(description='error occurred: channel ID is not valid') db_connect = DbConnector() db_connect.cursor() sql = "SELECT is_public FROM project.channel_data WHERE channel_id = (%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() # check channel is valid if ret is None: raise InputError(description='error occurred: channel ID is not valid') if ret[0] is False and not user_is_flockr_owner(u_id): raise AccessError( description='error occurred: channel ID refers to a private channel' ) sql = "SELECT member, owner FROM project.channel_data WHERE channel_id = (%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() member_list = ret[0] owner_list = ret[1] # update database sql = "UPDATE project.channel_data SET member=(%s), owner=(%s) WHERE channel_id=(%s)" member_list.append(u_id) # if user is flockr then become onwer if user_is_flockr_owner(u_id): owner_list.append(u_id) value = (member_list, owner_list, channel_id) db_connect.execute(sql, value) # close database connection db_connect.close() return {}
def channel_leave(token: str, channel_id: int): """ Given a channel ID, the user removed as a member of this channel :param token: user's token :param channel_id: channel's id :return: if user leave the channel successfully, it will return an empty dictionary """ # check token if valid token_operation = TokenJwt() if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # get user's u_id from token u_id = token_operation.get_uid(token) db_connect = DbConnector() db_connect.cursor() sql = "SELECT member, owner FROM project.channel_data WHERE channel_id = (%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() # check if the channel is valid if ret is None: raise InputError( description='error occurred: the channel ID is not a valid channel' ) member_list = ret[0] owner_list = ret[1] # check if the user is valid if u_id not in member_list: raise AccessError(description='error occurred: the authorised user ' 'is not a member of channel with this channel_id') # remove user from member_list member_list.remove(u_id) # if owner, remove from owner_list if u_id in owner_list: owner_list.remove(u_id) # UPDATE database db_connect.cursor() sql = "UPDATE project.channel_data SET member=(%s),owner=(%s) WHERE channel_id=(%s)" value = (member_list, owner_list, channel_id) db_connect.execute(sql, value) # close database connection db_connect.close() return {}
def channels_list(token: str) -> dict: """ Provide a list of all channels (and their associated details) that the authorised user is part of :param token: user's token :return: dictionary of list of dictionary with keys 'channel_id' and 'name' which includes the channels that the user is a part of """ dictionary = { 'channels': [], } token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # get user's u_id from token u_id = token_operation.get_uid(token) # get info in database db_connect = DbConnector() db_connect.cursor() sql = ''' SELECT channel_id, name FROM project.channel_data c INNER JOIN project.user_data u ON u.u_id = ANY (c.member) WHERE u.u_id = (%s); ''' value = (u_id, ) db_connect.execute(sql, value) ret = db_connect.fetchall() for channel in ret: dictionary["channels"].append({ 'channel_id': channel[0], 'name': channel[1] }) db_connect.close() return dictionary
def standup_start(token, channel_id, length): token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # check channel_id is not valid db_connect = DbConnector() db_connect.cursor() sql = "SELECT channel_id FROM project.channel_data WHERE channel_id=(%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret is None: raise InputError( description='error occured: Channel ID is not a valid channel') curr_time = int(time.time()) exist_active = standup_active(token, channel_id)["is_active"] if exist_active is True: raise InputError(description='error occurred:\ An active standup is currently running in this channel' ) finish_time = curr_time + length # get id from token u_id = token_operation.get_uid(token) sql = "INSERT INTO project.active_data (standup_uid, channel_id, time_finish) VALUES (%s,%s,%s)" value = (u_id, channel_id, int(finish_time)) db_connect.execute(sql, value) # time_dict = { # 'standup_uid': u_id, # 'channel_id': channel_id, # 'time_finish': int(finish_time), # 'message': "" # } # ACTIVE_DATA.append(time_dict) time1 = threading.Timer(length, send_standup_message, [channel_id]) time1.start() return {'time_finish': int(finish_time)}
def user_profile(token, u_id): # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') db_connect = DbConnector() db_connect.cursor() sql = "SELECT email, name_first, name_last, handle, \ profile_img_url FROM project.user_data WHERE u_id=(%s);" value = (u_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() # check uid is valid if ret is None: raise InputError( description='error occurred: User with u_id is not a valid user') user_dict = {} # for return email = ret[0] name_first = ret[1] name_last = ret[2] handle_str = ret[3] profile_img_url = ret[4] user_dict['u_id'] = u_id user_dict['email'] = email user_dict['name_first'] = name_first user_dict['name_last'] = name_last user_dict['handle_str'] = handle_str user_dict['profile_img_url'] = profile_img_url # close database connection db_connect.close() return {'user': user_dict}
def user_profile_setemail(token, email): # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') exist_change = False regex = r'^[a-z0-9]+[\._]?[a-z0-9]+[@]\w+[.]\w{2,3}$' if re.search(regex, email): # check Email entered is valid exist_change = True if exist_change is False: raise InputError( description='error occurred: email entered is not valid') # check email address is independent db_connect = DbConnector() db_connect.cursor() sql = "SELECT email FROM project.user_data WHERE email=(%s);" value = (email, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret is not None: raise InputError( description='error occurred: email is already used by another user' ) # get user's u_id from token token_operation = TokenJwt() u_id = token_operation.get_uid(token) sql = "UPDATE project.user_data SET email=(%s) WHERE u_id=(%s)" value = (email, u_id) db_connect.execute(sql, value) db_connect.close() return {}
def channel_messages(token: str, channel_id: int, start: int): """ Given a Channel with ID channel_id that the authorised user is part of, return up to 50 messages between index "start" and "start + 50" :param token: the authorised user's token :param channel_id: the channel ID :param start: the start number :return: dictionary of messages as required """ token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # start = int(start) # channel_id = int(channel_id) db_connect = DbConnector() db_connect.cursor() sql = "SELECT member FROM project.channel_data WHERE channel_id=(%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() # check channel_id is valid if ret is None: raise InputError(description='error occurred: channel id is not valid') member_list = ret[0] # get user's u_id from token u_id = token_operation.get_uid(token) # check u_id is a member for the channel if u_id not in member_list: raise AccessError( description='Authorised user is not a member of channel') # check start valid sql = "SELECT COUNT(*) FROM project.message_data WHERE channel_id=(%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() total_message = ret[0] # start is greater than the total number of messages if start > total_message: raise InputError(description='error occurred: start is greater than ' 'the total number of messages') # determine end retuen_end = -1 if total_message > start + 50: end = start + 50 retuen_end = end else: end = total_message # store all the required messages msg = [] sql = "SELECT * FROM project.message_data WHERE channel_id=(%s) ORDER BY time_created DESC" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchall() for detail in ret: react_uid = detail[6] if u_id in react_uid: react_cond = True else: react_cond = False msg.append({ 'message_id': detail[0], 'channel_id': detail[1], 'time_created': detail[3], 'u_id': detail[4], 'message': detail[2], 'is_pinned': detail[5], 'reacts': [{ 'is_this_user_reacted': react_cond, 'react_id': 1, 'u_ids': react_uid }] }) # close database connection db_connect.close() return {'messages': msg, 'start': start, 'end': retuen_end}
def sample(self, N=100, stor_dir='../evaluation', T=0.7, fold=[1], epoch=[9], valid=True, novel=True, unique=True, write_csv=True): '''Sample from a model where the number of novel valid unique molecules is fixed :param stor_dir: directory where the generated SMILES are saved :param N: number of samples :param T: Temperature :param fold: Folds to use for sampling :param epoch: Epochs to use for sampling :param valid: If True, only accept valid SMILES :param novel: If True, only accept novel SMILES :param unique: If True, only accept unique SMILES :param write_csv If True, the generated SMILES are written in stor_dir :return: res_molecules: list with all the generated SMILES ''' res_molecules = [] print('Sampling: started') for f in fold: for e in epoch: self._model.build(stor_dir + '/' + self._experiment_name + '/models/model_fold_' + str(f) + '_epochs_' + str(e)) new_molecules = [] while len(new_molecules) < N: new_mol = self._encoder.decode( self._model.sample(self._starting_token, T)) # Remove remains from generation new_mol = clean_molecule(new_mol[0], self._model_type) # If not valid, get new molecule if valid and not check_valid(new_mol): continue # If not unique, get new molecule if unique and (new_mol in new_molecules): continue # If not novel, get molecule if novel and (new_mol in self._data): continue # If all conditions checked, add new molecule new_molecules.append(new_mol) # Prepare name for file name = 'molecules_fold_' + str(f) + '_epochs_' + str( e) + '_T_' + str(T) + '_N_' + str(N) + '.csv' if unique: name = 'unique_' + name if valid: name = 'valid_' + name if novel: name = 'novel_' + name # Store final molecules if write_csv: if not os.path.exists(stor_dir + '/' + self._experiment_name + '/molecules/'): os.makedirs(stor_dir + '/' + self._experiment_name + '/molecules/') mol = np.array(new_molecules).reshape(-1) pd.DataFrame(mol).to_csv(stor_dir + '/' + self._experiment_name + '/molecules/' + name, header=None) res_molecules.append(new_molecules) print('Sampling: done') return res_molecules
def channel_details(token: str, channel_id: int) -> dict: """ Given a Channel with ID channel_id that the authorised user is part of, provide basic details about the channel :param token: user's token :param channel_id: channel's id :return: a dictionary with keys 'name', 'owner_members' and 'all_members' """ token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # get the user's u_id from token u_id = token_operation.get_uid(token) # get info for the channel db_connect = DbConnector() db_connect.cursor() sql = "SELECT * FROM project.channel_data WHERE channel_id = (%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchall() # check if channel id invalid if len(ret) == 0: raise InputError( description='error occurred: the channel ID is not a valid channel' ) channel_name = ret[0][1] member_list = ret[0][2] owner_list = ret[0][3] # check if the authorised user is member of this channel if u_id not in member_list: raise AccessError(description='error occurred: the authorised user ' 'is not a member of channel with this channel_id') # get channel member basic information db_connect.cursor() sql = ''' DROP TABLE IF EXISTS project.detail_data; CREATE TABLE project.detail_data ( id serial NOT NULL, u_id int ); INSERT INTO project.detail_data(u_id) select unnest(( SELECT member FROM project.channel_data WHERE channel_id = (%s))); SELECT u.u_id, name_last, name_first, profile_img_url FROM project.user_data u INNER JOIN project.detail_data d ON u.u_id = d.u_id ORDER BY d.id; ''' value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchall() all_members = [] # get member details for detail in ret: all_members.append({ 'u_id': detail[0], 'name_last': detail[1], 'name_first': detail[2], 'profile_img_url': detail[3] }) # get owner details owner_members = [] for member in all_members: if member['u_id'] in owner_list: owner_members.append(member) # close database connection db_connect.close() details = { 'name': channel_name, 'owner_members': owner_members, 'all_members': all_members } return details
def channel_invite(token: str, channel_id: int, u_id: int) -> dict: """ Invites a user (with user id u_id) to join a channel with ID channel_id. Once invited the user is added to the channel immediately :param token: token of user who try to invite user :param channel_id: the id of channel which the user will be invited in :param u_id: uid of user who has been invited to join the channel :return: if it can successfully invite somebody to this channel, it will return an empty dictionary """ token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # check if channel id is valid db_connect = DbConnector() db_connect.cursor() sql = "SELECT channel_id FROM project.channel_data WHERE channel_id = (%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret is None: raise InputError( description= 'error occurred: channel_id does not refer to a valid channel') # check if uid is valid sql = "SELECT u_id FROM project.user_data WHERE u_id = (%s)" value = (u_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret is None: raise InputError( description='error occurred: u_id does not refer to a valid user') # check if the authorised user( is a member of the channel) authorised_uid = token_operation.get_uid(token) sql = "SELECT member, owner FROM project.channel_data WHERE channel_id =(%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() member_list = ret[0] owner_list = ret[1] if authorised_uid not in member_list: raise AccessError(description='error occurred: the authorised user ' 'is not a member of the channel') # get flockr owner list sql = "SELECT owner FROM project.flockr_data;" db_connect.execute(sql) ret = db_connect.fetchone() flockr_list = ret[0] # if no error, add the user to the channel if u_id not in member_list: sql = "UPDATE project.channel_data SET member=(%s), owner=(%s) WHERE channel_id=(%s);" # if invite flockr, flockr will be owner if u_id in flockr_list: member_list.append(u_id) owner_list.append(u_id) value = (member_list, owner_list, channel_id) else: member_list.append(u_id) value = (member_list, owner_list, channel_id) db_connect.execute(sql, value) db_connect.close() return {}
def standup_send(token, channel_id, message): token_operation = TokenJwt() # check if the token is valid if check_valid(token) is False: raise AccessError(description='error occurred: token is not valid') # check channel id is valid db_connect = DbConnector() db_connect.cursor() sql = "SELECT member FROM project.channel_data WHERE channel_id=(%s);" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret is None: raise InputError(description='error occurred: channel is not valid') # get member list member_list = ret[0] # check if the message longer than 1000 if len(message) > 1000: raise InputError(description='Message is more than 1000 characters') exist_active = standup_active(token, channel_id)["is_active"] if not exist_active: raise InputError( description='error occurred: no standup is running in this channel' ) u_id = token_operation.get_uid(token) # check user is valid if u_id not in member_list: raise AccessError( description='error occurred: user is not a member of this channel') # get handle sql = "SELECT handle FROM project.user_data WHERE u_id=(%s)" value = (u_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() handle = ret[0] # get msg from active buffer sql = "SELECT message FROM project.active_data WHERE channel_id=(%s)" value = (channel_id, ) db_connect.execute(sql, value) ret = db_connect.fetchone() if ret[0] is not None: message_stand = ret[0] message_stand += "\n" + handle + ": " + message else: message_stand = handle + ": " + message # add to active data sql = "UPDATE project.active_data SET message=(%s) WHERE channel_id=(%s);" value = (message_stand, channel_id) db_connect.execute(sql, value) # close database connection db_connect.close() return {}
def eval_molecule(self, stor_dir='.'): '''Plot percentage of novel, valid and unique SMILES :return: ''' valid = np.zeros((self._n_folds, self._epochs)) unique = np.zeros((self._n_folds, self._epochs)) novel = np.zeros((self._n_folds, self._epochs)) for i in range(self._n_folds): for j in range(self._epochs): mol = pd.read_csv(stor_dir + '/' + self._experiment_name + '/molecules/molecule_fold_' + str(i + 1) + '_epochs_' + str(j) + '.csv', header=None).values[:, 1].astype(str) # Remove padding for k, m in enumerate(mol): mol[k] = clean_molecule(m, self._model_type) # Compute unique molecules unique[i, j] = len(set(mol)) / self._samples # Remove duplicates mol = np.array(list(set(mol))) # Check validity and remove non-valid molecules to_delete = [] for k, m in enumerate(mol): if not check_valid(m): to_delete.append(k) valid_mol = np.delete(mol, to_delete) valid[i, j] = len(valid_mol) / self._samples # Compute molecules unequal to training data if valid_mol.size != 0: new_m = self.check_with_training_data(list(valid_mol)) novel[i, j] = len(new_m) / self._samples # Get percentage unique *= 100 novel *= 100 valid *= 100 # Get mean values mean_unique = np.mean(unique, axis=0) mean_valid = np.mean(valid, axis=0) mean_novel = np.mean(novel, axis=0) # Get standard deviation std_unique = np.std(unique, axis=0) std_valid = np.std(valid, axis=0) std_novel = np.std(novel, axis=0) print(mean_unique) print(mean_valid) print(mean_novel) # PLot plt.figure(1) plt.errorbar(np.arange(1, self._epochs + 1), mean_unique, yerr=std_unique, capsize=3, label='unique') plt.errorbar(np.arange(1, self._epochs + 1), mean_valid, yerr=std_valid, capsize=3, label='valid & unique') plt.errorbar(np.arange(1, self._epochs + 1), mean_novel, yerr=std_novel, capsize=3, label='novel, valid & unique', linestyle=':') plt.yticks(np.arange(0, 110, step=10)) plt.legend() plt.ylim(0, 105) plt.title('SMILES T=' + str(self._T)) plt.ylabel('% SMILES') plt.xlabel('Epoch') plt.savefig(stor_dir + '/' + self._experiment_name + '/molecules/novel_valid_unique_molecules.png') # Store data data = np.vstack((mean_unique, std_unique, mean_valid, std_valid, mean_novel, std_novel)) pd.DataFrame(data).to_csv(self._experiment_name + '/molecules/' + self._experiment_name + '_data.csv') plt.show()