


import json
import logging
import os
import socket

import git
import numpy as np
import torch


logging.basicConfig(
    format='''%(asctime)s - %(levelname)s - %(name)s - PID: %(process)d -  %(message)s''',
    datefmt='''%m/%d/%Y %H:%M:%S''',
    level=logging.INFO,
)
snake_case							: List[Any]      =   logging.getLogger(__name__)






def 							__lowercase     (				__lowerCAmelCase							:       str     ):
							a__    =  git.Repo(search_parent_directories=__lowerCAmelCase     )
							a__    =  {
							    'repo_id': str(__lowerCAmelCase     ),
							    'repo_sha': str(repo.head.object.hexsha     ),
							    'repo_branch': str(repo.active_branch     ),
							}

							with open(os.path.join(__lowerCAmelCase      ,					'git_log.json'     )      ,					'w'     ) as f:
														json.dump(__lowerCAmelCase      ,					__lowerCAmelCase      ,					indent=4     )






def 							__lowercase     (				__lowerCAmelCase							:       Union[str, Any]     ):
							if params.n_gpu <= 0:
														a__    =  0
														a__    =  -1
														a__    =  True
														a__    =  False
														return

							assert torch.cuda.is_available()

							logger.info('Initializing GPUs'     )
							if params.n_gpu > 1:
														assert params.local_rank != -1

														a__    =  int(os.environ['WORLD_SIZE']     )
														a__    =  int(os.environ['N_GPU_NODE']     )
														a__    =  int(os.environ['RANK']     )

														# number of nodes / node ID
														a__    =  params.world_size // params.n_gpu_per_node
														a__    =  params.global_rank // params.n_gpu_per_node
														a__    =  True

														assert params.n_nodes == int(os.environ['N_NODES']     )
														assert params.node_id == int(os.environ['NODE_RANK']     )

							# local job (single GPU)
							else:
														assert params.local_rank == -1

														a__    =  1
														a__    =  0
														a__    =  0
														a__    =  0
														a__    =  1
														a__    =  1
														a__    =  False

							# sanity checks
							assert params.n_nodes >= 1
							assert 0 <= params.node_id < params.n_nodes
							assert 0 <= params.local_rank <= params.global_rank < params.world_size
							assert params.world_size == params.n_nodes * params.n_gpu_per_node

							# define whether this is the master process / if we are in multi-node distributed mode
							a__    =  params.node_id == 0 and params.local_rank == 0
							a__    =  params.n_nodes > 1

							# summary
							a__    =  F'--- Global rank: {params.global_rank} - '
							logger.info(PREFIX + 'Number of nodes: %i' % params.n_nodes     )
							logger.info(PREFIX + 'Node ID        : %i' % params.node_id     )
							logger.info(PREFIX + 'Local rank     : %i' % params.local_rank     )
							logger.info(PREFIX + 'World size     : %i' % params.world_size     )
							logger.info(PREFIX + 'GPUs per node  : %i' % params.n_gpu_per_node     )
							logger.info(PREFIX + 'Master         : %s' % str(params.is_master     )     )
							logger.info(PREFIX + 'Multi-node     : %s' % str(params.multi_node     )     )
							logger.info(PREFIX + 'Multi-GPU      : %s' % str(params.multi_gpu     )     )
							logger.info(PREFIX + 'Hostname       : %s' % socket.gethostname()     )

							# set GPU device
							torch.cuda.set_device(params.local_rank     )

							# initialize multi-GPU
							if params.multi_gpu:
														logger.info('Initializing PyTorch distributed'     )
														torch.distributed.init_process_group(
														    init_method='env://'      ,					backend='nccl'      ,					)






def 							__lowercase     (				__lowerCAmelCase							:       Dict     ):
							np.random.seed(args.seed     )
							torch.manual_seed(args.seed     )
							if args.n_gpu > 0:
														torch.cuda.manual_seed_all(args.seed     )








def 							__lowercase     (				__lowerCAmelCase							:       list      ,					__lowerCAmelCase							:       list      ,					__lowerCAmelCase							:       int     ):
							if len(__lowerCAmelCase     ) != len(__lowerCAmelCase     ):
														raise ValueError('The length of profit and weight must be same.'     )
							if max_weight <= 0:
														raise ValueError('max_weight must greater than zero.'     )
							if any(p < 0 for p in profit     ):
														raise ValueError('Profit can not be negative.'     )
							if any(w < 0 for w in weight     ):
														raise ValueError('Weight can not be negative.'     )

							# List created to store profit gained for the 1kg in case of each weight
							# respectively.  Calculate and append profit/weight for each element.
							a__    =  [p / w for p, w in zip(__lowerCAmelCase      ,					__lowerCAmelCase     )]

							# Creating a copy of the list and sorting profit/weight in ascending order
							a__    =  sorted(__lowerCAmelCase     )

							# declaring useful variables
							a__    =  len(__lowerCAmelCase     )
							a__    =  0
							a__    =  0
							a__    =  0

							# loop till the total weight do not reach max limit e.g. 15 kg and till i<length
							while limit <= max_weight and i < length:
														# flag value for encountered greatest element in sorted_profit_by_weight
														a__    =  sorted_profit_by_weight[length - i - 1]
														a__    =  profit_by_weight.index(__lowerCAmelCase     )
														a__    =  -1

														# check if the weight encountered is less than the total weight
														# encountered before.
														if max_weight - limit >= weight[index]:
																					limit += weight[index]
																					# Adding profit gained for the given weight 1 ===
																					# weight[index]/weight[index]
																					gain += 1 * profit[index]
														else:
																					# Since the weight encountered is greater than limit, therefore take the
																					# required number of remaining kgs and calculate profit for it.
																					# weight remaining / weight[index]
																					gain += (max_weight - limit) / weight[index] * profit[index]
																					break
														i += 1
							return gain


if __name__ == "__main__":
						print(
						    '''Input profits, weights, and then max_weight (all positive ints) separated by '''
						    '''spaces.'''
						)

						snake_case							: Tuple      =   [int(x) for x in input('''Input profits separated by spaces: ''').split()]
						snake_case							: Optional[int]      =   [int(x) for x in input('''Input weights separated by spaces: ''').split()]
						snake_case							: List[str]      =   int(input('''Max weight allowed: '''))

						# Function Call
						calc_profit(profit, weight, max_weight)




