## Instructions

**Objective**

Write a program to implement random samples in python language.

## Requirements and Specifications

**D. Random Samples**

Sometimes we have so much data that we want to work with a smaller random sample of it. (1) Write a python assignment function

**random_sample(data_list, sample_size)**that returns a new list of**sample_size**random elements from**data_list**. You can assume that the sample size is a non-negative integer no larger than the length of the data list. It should not change the original input list.The intended meaning is to sample the data without replacement. For example, consider

**random_sample([1, 2, 3], 2)**. Possible answers would include**[1, 3]**and**[3, 2].**However, the answer**[2, 2]**would not be correct, because there's only one**2**in the input that we can possibly pick. Similarly,**random_sample([1, 2, 2, 3], 3**) might return**[2, 1, 2]**, but not**[2, 2, 2]**.Do not use the function

**random.sample()**. However, look at what else the**random**module offers.**E. Weighted Random Choice**

Sometimes you would like to choose among a set of options equally. Other times, you would like different options to have different probabilities of being selected (a weighted random choice). For example, if you wanted to pick random numbers with the same frequency as they occurred in some input, you would use the frequency of occurrence in the input as the probability distribution for the selection.

(2) Write a function

**random_choice(data_dict)**that takes a dictionary as input and randomly selects one of the keys of the dictionary. The values in the dictionary should be the probability (a value between 0 and 1) of selecting the associated key. All values should add up to 1.Do not use the function

**random.choices()**. However, take an original approach.If you repeatedly call the function enough times, the distribution of the output should look identical to the input.

**F. Histograms**

A histogram is a graphical representation of tabulated frequencies of data. It groups data into ranges and counts the number of values in each bin. For this problem, you will write a function that does this computation of grouping and counting. The provided template has code to produce the graphical representation.

(3) Write a function

**hist_data(score_list)**that takes a list of scores. You can assume each score is a number in the range 0 ≤ score < 100. It returns a list of five numbers — counts of the number of scores in each of five equal-sized ranges.For example,

**hist_data([20, 45, 38, 19, 77, 39, 20, 90, 22])**should return**[1, 5, 1, 1, 1]**. There is 1 number in the range 0…19.99, 5 in the range 20…39.99, 1 in the range 40…59.99, etc.**Source Code**

```
import random
def random_sample(data_list, sample_size):
# First, create a copy of data_list
data_list_copy = data_list.copy()
# Size of list
N = len(data_list)
# list that will contain the samples
samples = list()
# Now, generate random numbers from 0 to N -1
while len(samples) < sample_size:
n = random.randint(0, N-1) # 0 to N-1
# Append element to return list
samples.append(data_list_copy[n])
# Delete element from data_list_copy
del data_list_copy[n]
# Get the new size of the list of elements
N = len(data_list_copy)
return samples
def random_choice(data_dict):
# First, create a copy of the dict
data_dict_copy = data_dict.copy()
# Sort dict by values in descending order
data_dict_copy = dict(sorted(data_dict_copy.items(), key = lambda item: item[1], reverse = True))
# Get keys in a list
keys = list(data_dict_copy.keys())
# Get values in a list
values = list(data_dict_copy.values())
# Check that all values add up to 1
assert abs(sum(values) -1) < 1E-3, "All values should add up to 1"
# Generate a random number between 0 and 1
r = random.uniform(0, 1)
upto = 0
for key in data_dict_copy:
if upto + data_dict_copy[key] >= r:
return key
upto += data_dict_copy[key]
return None
def hist_data(score_list):
# First, create a list that will hold the count of the gropus
count = [0, 0, 0, 0, 0] # 5 elements
# Now, check each value
for val in score_list:
if val in range(0, 20): # between 0 and 19.999...
count[0] += 1
elif val in range(20, 40): # between 20 and 39.999....
count[1] += 1
elif val in range(40, 60): # between 40 and 59.999....
count[2] += 1
elif val in range(60, 80): # between 60 and 79.999...
count[3] += 1
else: # between 80 and 100
count[4] += 1
return count
if __name__ == '__main__':
# Test random_sample
print(random_sample([1,2,3], 2))
print(random_sample([1,2,2,3], 3))
# Test random_choice
print(random_choice({"a": 0.8, "b": 0.1, "c": 0.05, "d": 0.05}))
print(random_choice({"a": 0.1, "b": 0.7, "c": 0.1, "d": 0.1}))
#print(random_choice({"a": 0.2, "b": 0.8, "c": 0.1})) # Should return an error saying that the sum of the values is not 1
# Test hist_data
print(hist_data([20,45,38,19,77,39,20,90,22])) # should return [1,5,1,1,1]
print(hist_data([1,5,8,7,48,49,90])) # should return [4, 0, 2, 0, 1]
```