The output of the code is in different order than expected - python-3.x

n = int(input())
a_name = []
a_score = []
for _ in range(n):
name = input()
score = float(input())
a_name.append(name)
a_score.append(score)
a_score1 = set(a_score)
a_score1.remove(min(a_score1))
x = min(a_score1)
for i in range(n):
if a_score[i]==x:
print(a_name[i])
For the following code input is:
5
Harry
37.21
Berry
37.21
Tina
37.2
Akriti
41
Harsh
39
My Output:
Harry
Berry
Expected Output:
Berry
Harry
I am a newbie in the programming world and would appreciate help to solve this.
This is a hacker rank problem and the problem is to find the names with a second minimum score. I was able to pass 8/10 test cases but 2 test cases are failing with this solution. I am able to find the correct names(i.e. names with second-lowest score) however it is printed in wrong order)

you can find first the second minim and then find the names that have the second minim using a list comprehension and the built-in function zip:
second_minim = sorted(a_score)[1]
[n for n, s in zip(a_name, a_score) if s == second_minim]
output:
['Harry', 'Berry']
related to why should be ['Berry', 'Harry'] instead of ['Harry', 'Berry'] according to the requirements that you pointed:
If there are multiple students with the same grade, order their names alphabetically and print each name on a new line
so you should use:
result = sorted(n for n, s in zip(a_name, a_score) if s == second_minim)
print(*result, sep='\n')
output:
Berry
Harry

So instead of using two lists, you can map the scores to a name with a dict. Like so:
scores_dict = {'Harry': 37.21,
'Berry': 37.21,
'Tina': 37.2,
'Akriti': 41,
'Harsh': 39
}
Next remove all matching keys to the starting min value so that we can get the second min
x = min(scores_dict, key=scores_dict.get)
filtered_scores = {k:v for k,v in scores_dict.items() if v != scores_dict[x]}
Then we grab all the keys of any of the new min value.
x = min(filtered_scores, key=scores_dict.get)
res = [key for key in filtered_scores if filtered_scores[key] == filtered_scores[x]]
Full Code
n = int(input)
scores_dict = {}
for _ in range(n):
name = input()
score = int(input())
scores_dict[name] = score
# The loop will produce this dict
'''
scores_dict = {'Harry': 37.21,
'Berry': 37.21,
'Tina': 37.2,
'Akriti': 41,
'Harsh': 39
}
'''
x = min(scores_dict, key=scores_dict.get)
filtered_scores = {k:v for k,v in scores_dict.items() if v != scores_dict[x]}
x = min(filtered_scores, key=scores_dict.get)
res = [key for key in filtered_scores if filtered_scores[key] == filtered_scores[x]]
print(res)
If you really want to use two lists, it can be done, but it adds potential for bugs by adding unneeded complexity.
Dictionaries are just associative (named) arrays (lists).

n = int(input())
a_name = []
a_score = []
for _ in range(n):
name = input()
score = float(input())
a_name.append(name)
a_score.append(score)
a_score1 = set(a_score)
a_score1.remove(min(a_score1))
x = min(a_score1)
y =[]
for i in range(n):
if a_score[i]==x:
y.append(a_name[i])
y.sort()
for j in range(len(y)):
print(y[j])
I got the output with this code. Thank you everyone for the help!

Related

comparing lists in a list

Hi I was trying to do an exercise in which you get n lines of two numbers separated by space as inputs(for example a product info). The first number is price of the product and the second one is value of it and the goal is to find if there is any product which price is lower and it's value is higher for example :
2
4 5
3 6
This condition should print(yes), but this for example:
3
7 9
4 6
3 2
should print(no)
I came up with this :
n = int(input())
a = []
for x in range(n):
a.append(input().split( ))
for m in range(n):
a[m][0] = int(a[m][0])
a[m][1] = int(a[m][1])
b = max(a)
for z in range(n):
a[z].reverse()
c = max(a)
c.reverse()
if c == b:
print('no')
else:
print('yes')
But it's not working for this [[1,3],[3,1]] and same ones and it's obvious why but anyway can anyone help me somehow find a solution ?
hi again as I did not receive any answer on this topic so I decide to post an answer when I find one and here it is:
a = [input().split( ) for i in range(int(input()))]
b = []
for m in range(len(a)):
a[m][0] = int(a[m][0])
a[m][1] = int(a[m][1])
for x in range(len(a)):
for z in range(x+1,len(a.copy())):
if (a[x][0] < a[z][0] and a[x][1] > a[z][1]) or (a[x][0] > a[z][0] and a[x][1] < a[z][1]):
b.append([1])
elif (a[x][0] > a[z][0] and a[x][1] > a[z][1]) or (a[x][0] < a[z][0] and a[x][1] < a[z][1]):
b.append([2])
if [1] in b:
print('yes')
else:
print('no')
hope you enjoy !

conting of input names

I have a python homework which I need to take n from input to know how many names I have to take from input, save them to a dictionary then count how many each name was inputed, something like voting system.
so far I couldn't save my input into a dic.
Because I stored all inputs in a list after I assign my list with a dict, it turns to str.
for example:
how many vote u want to input : 4
take your votes:
jack
jasmin
jack
sara
result:
jack 2
jasmin 1
sara 1
My code:
vorodi=[]
n=int(input())
counter={}
for i in range(0,n):
vorodi.append(input())
for letter in vorodi:
if letter not in counter:
counter[letter]+=1
else:
counter[letter]=1
print(counter)
This is a classic case where you will want to use defaultdict. With defaultdict you specify the type of new keys and so if the key is not present it will be initialized to the default of the type specified. So you could do:
from collections import defaultdict
n = int(input())
counter = defaultdict(int)
for i in range(n):
counter[input()] += 1
print(counter.items())
OR:
with regular dict using the get method with the default argument:
n = int(input())
counter = {}
for i in range(n):
name = input()
count = counter.get(name, 0)
counter[name] = count + 1
OR:
with regular dict using the setdefault method with the default argument:
n = int(input())
counter = {}
for i in range(n):
name = input()
counter.setdefault(name, 0)
counter[name] += 1
To print it as you showed you can simply iterate the dict afterwards:
for k,v in counter.items():
print(k, v)

How to print the index/elements that are included in the final max sum of non-adjacent elements?

In the program of finding the max sum of non-adjacent elements how can we print the elements/indexes of elements which are considered in the final sum. So here I am attaching my code for that. I am using dynamic programming.
I got the correct answer when there is only one possibility of occurring max sum like we have -1, 2, 4, 5. So the output will be 5 and 2.
n = int(input())
tickets = list(map(int,input().split()))
incl = 0
excl = 0
max_list = []
for i in range(len(tickets)):
if excl>incl:
new_excl = excl
else:
new_excl = incl
incl = excl + tickets[i]
excl = new_excl
if excl > incl:
if len(max_list)>1 and (max_list[len(max_list)-1] - max_list[len(max_list)-2])==1:
del max_list[len(max_list)-2]
else:
max_list += [i]
if excl>incl:
print(excl,max_list)
else:
print(incl,max_list)
But I do not get answers when the input like this : 4, 5, 4, 3. In this input there are two possibilities : 4+4 and 5+3. I want to print that possibility that has a higher digits than the other from right side. So in this example from right side 4 > 3 so the possibility of 4 should be printed. But I got all the elements in the list.
I have to solve this problem. This is problem from the techgig's code gladiators qualification round. I find the answer for my problem but anyway this solution doesn't get me 100 marks. I haven't checked it for many test cases but you can check it and if it fails then please inform so I can get what the problem is.
from itertools import combinations
for i in range(int(input())):
n = int(input())
tickets = list(map(int,input().split()))
incl = 0
excl = 0
max_list = []
for i in range(len(tickets)):
if excl>incl:
new_excl = excl
else:
new_excl = incl
incl = excl + tickets[i]
excl = new_excl
if excl > incl:
if len(max_list)>1 and (max_list[len(max_list)-1] - max_list[len(max_list)-2])==1:
del max_list[len(max_list)-2]
else:
max_list += [i]
if excl>incl:
s=excl
else:
s=incl
a=[]
if 1 in [abs(t-s) for s,t in zip(max_list,max_list[1:])]:
for m in range(2,n):
for n in list(combinations(max_list, m)):
if sum(tickets[b] for b in n)==s:
a+=[n]
l=[]
index=[]
for m in a:
l+=[tickets[m[1]]]
index+=[m[1]]
v = index[l.index(max(l))]
for m in a:
if v in m:
ans = m
break
for d in list(reversed(ans)):
print(tickets[d],end='')
print()
else:
max_list.reverse()
for d in max_list:
print(tickets[d],end='')
print()

Lazy Sorting HackerRank Python

I am new to coding and so the following code I wrote may be incorrect or sub-optimal. However, the problem I have is that I do not understand the input and thus cannot get the code to run (I only tested it with custom inputs).
The essence of the problem is that you have some sequence of numbers and you want to arrange the sequence monotonically (nondecreasing or nonincreasing). You do this by a random shuffle. How many shuffles does it take for you to get to the monotonic sequence via a random shuffle? You can find the problem here and here is my code below:
#!/bin/python3 ------ The following import is given in the prompt
import os
import sys
# Complete the solve function below. Here is my code below
def solve(P):
P.sort()
correct = P
count = []
i = 0
# Here I am trying to calculate the number of ways to get the desired monotonic sequence
# I count the number of repeated numbers in the sequence as separate items in a list
for j in range(i,len(correct)):
if correct[i] != correct[j] or i == len(correct) - 1:
count.append(j-i)
i = j
j = len(correct)
else:
j = j + 1
summ = 0
for k in range(len(count)):
summ = summ + count[k]
if summ == len(correct):
i = len(correct)
poss = [1]*len(count)
for k in range(len(count)):
for l in range(1,count[k]+1):
poss[k] = poss[k]*l
possible = 1
for x in poss:
possible = possible * x
# This is calculating the number of different permutations of n distinct elements
total = 1
n = len(correct)
for i in range(1,n+1):
total = total * i
# Calculating the probability to the 6th decimal place
probability = float(possible / total)
expected = round(1/probability, 6)
print(expected)
# The following code is given in the prompt to input the test cases
if __name__ == '__main__':
fptr = open(os.environ['OUTPUT_PATH'], 'w')
P_count = int(input())
P = list(map(int, input().rstrip().split()))
result = solve(P)
fptr.write(str(result) + '\n')
fptr.close()
In my code, I just assumed that P is the sequence of numbers you receive from the input.

always got the same output with random.choice in a function

I tried using for-loop to exec my function but its always the same result.
import random
def main(arr):
result = random.choice(arr)
...some code...
return len(result)
for i in range(100):
main(arr)
I could only get diff result from stop/run the terminal. Anyone know why?
my question is the same as this one. random.choice always same
import random
results = []
with open('kargerMinCut.txt') as inputfile:
for line in inputfile:
results.append(line.strip().split('\t'))
def contract(arr):
while len(arr) > 2:
# Generate random number in list of lists
# ranList = random.choice(arr)
ranList = arr[np.random.choice(len(arr))]
ranNum = random.choice(ranList[1:])
# retrieve the index of the random number
listIndex = arr.index(ranList)
for i in range(0, len(arr)):
if arr[i][0] == ranNum:
targetList = i
break
target = ranList[0]
for i in range(0, len(arr)):
if i == listIndex:
arr[i].pop(0)
arr[i] = [x for x in arr[i] if x != ranNum]
elif i == targetList:
arr[i] = [x for x in arr[i] if x != target]
else:
for index, item in enumerate(arr[i]):
if item == target:
arr[i][index] = ranNum
arr[targetList] += arr[listIndex]
del arr[listIndex]
return len(arr[0])-1
the arr would be like this
array = [[1,2,3,4],[2,1,3,4],[3,1,2,4],[4,1,2,3]]
I don't know what you do inside your function but I've got the normal result. And in the question what you linked to the person just used seed. This is kinda pseudorandom that gives you all the time the same random output. Here is the link to deep your knowledge about pseudorandom
import random
arr = [1,2,3,4,5]
def main(arr):
result = random.choice(arr)
print(result)
for i in range(100):
main(arr)
The result is as it has to be:
1
3
5
3
4
3
1
4
4
3
2

Resources