Working with document, MAX, MIN values and list - python

I have a document in which a first number is a number of racers, the second is time in the first lap and the third is time in the second lap.
I want to count how many people were DNF in the first round, How many in the second, the Best time in the first round, the second round, and what was the best time.
r.n. 1. 2.
329 56 47
129 55 0
78 0 0
pretek = open ("26-pretek.txt", "r")
riadok = pretek.readline ()
preteky = []
x=0
y=0
while riadok != "" :
a = riadok.strip().split()
preteky.append (a)
riadok = pretek.readline ()
print(preteky)
if "0" in preteky[1]:
x+=1
print(x)
if "0" in preteky[2]:
y+=1
print(y)
naj1=min(preteky[2])
naj2=max(preteky[2])
print(naj1)
print(naj2)

Related

finding which person got highest percentage according to their marks

The first line of the input contains an integer which represents the number of lines
The next n lines represent a space-separated list of the person and their marks in the four subjects
output should be name of the highest percentage?
for example
input:-
4
Manoj 30 40 45 63
Shivam 38 29 45 60
Siddheshwar 38 35 39 45
Ananya 45 29 30 51
Output:-
Manoj
code :-
details_vertical=[]
for ctr in range(4):
details_vertical.append(input().split())
for name,marks,marks,marks in zip(*details_vertical):
print(f"{name}")
Is this something that you're looking for? Try it first, and ask questions.
There is room to improve it, but this is prob. most straightforward way.
details =[]
highest = 0
for i in range(4):
details = (input().split())
print(details) # just for debug, can comment out
total = sum(int(x) for x in details[1:]) # get this person's total
# change this print line to get average printout:
print(total / len(details[1:]) # it allows you have n+ scores flexibility - not assuming it's 4 only!
if total > highest: # processing along the way, so we don't have to save all the scores...
highest = total
best = details[0] # the person
print(best) # Manoj
is this you are looking for ?
input = """4
Manoj 30 40 45 63
Shivam 38 29 45 60
Siddheshwar 38 35 39 45
Ananya 45 29 30 51"""
# load data from row 1
x = input.split('\n')[1:]
x = [item.split() for item in x]
# append the average of 4 subject in last
y = [item + [sum([int(subitem) for subitem in item[1:]])/4] for item in x]
# sort the row by average
y.sort(key = lambda x:x[-1], reverse=True)
# first row first element is name with highest average
y[0][0]
This Solution might be an understandable one :
first_inp = int(input("No. of Students"))
no_of_subs = int(input("No. of Subjects :"))
details = {tuple(int(input("Marks")) for i in range(no_of_subs)):input("Name") for i in range(first_inp)}
lis_res = [sum(i) for i in details]
det_val = [v for v in details.values()]
print (det_val[lis_res.index(max(lis_res))])
In the end you can use return keyword to return that value if you are defining a function.

question regarding while loops and variable indexing

I am new to coding, so forgive me if this is answered elsewhere. I am not sure what to search for to find a relevant answer. I also am not sure if my title is even correct. I want to print out each value in C_numbers that is associated with the same index in barcode_names. I want to separate these numbers each time the value in barcode_names changes. So I am using a third list unique_barcodes to compare to.
barcode_names = [1111,1111,1111,2222,2222,2222,3333,3333]
C_numbers = [12,5,7,28,32,13,2,9]
unique_barcodes = [1111,2222,3333]
x = 0
y = 0
for z in barcode_names:
if barcode_names[x] == unique_barcodes[y]:
print(C_numbers[x])
x = x+1
else:
y = y+1
print('next page')
result:
12
5
7
next page
28
32
13
next page
For some reason, it doesn't print the last two values 2 and 9. How do I get it to continue looping until it finishes printing all the values?
You're looping over barcode_names, so the most iterations that loop can make is eight. Increasing y while printing next page counts as one of those iterations. This prevents you from doing the last two things you wanted to do, as then you'd need a total of ten iterations. To fix this, you need to keep looping as long as x is a valid index in barcode_names. Change for z in barcode_names: to while x < len(barcode_names):.
Using x and y was throwing off your loop and is why it didn't complete.
Maybe something like this is more simple?
barcode_names = [1111,1111,1111,2222,2222,2222,3333,3333]
C_numbers = [12,5,7,28,32,13,2,9]
last_name = barcode_names[0]
for i in range(len(barcode_names)):
barcode_name = barcode_names[i]
if not barcode_name == last_name:
last_name = barcode_name
print('next page')
print(C_numbers[i])
result:
12
5
7
next page
28
32
13
next page
2
9
The loop control variable z is not stopping itself from being incremented when y index value is incrementing. Hence, before your desired print, the loop gets terminated.
I found this by adding the following line to your code inside the loop at the beginning
print('z value: ', z)
i.e. complete program becomes:
barcode_names = [1111,1111,1111,2222,2222,2222,3333,3333]
C_numbers = [12,5,7,28,32,13,2,9]
unique_barcodes = [1111,2222,3333]
x = 0
y = 0
for z in barcode_names:
print('z value: ', z)
if barcode_names[x] == unique_barcodes[y]:
print(C_numbers[x])
x = x+1
else:
y = y+1
print('next page')
Output:
z value: 1111
12
z value: 1111
5
z value: 1111
7
z value: 2222
next page
z value: 2222
28
z value: 2222
32
z value: 3333
13
z value: 3333
next page
>
Try this instead:
barcode_names = [1111,1111,1111,2222,2222,2222,3333,3333]
C_numbers = [12,5,7,28,32,13,2,9]
unique_barcodes = [1111,2222,3333]
x = 0
y = 0
for z in barcode_names:
# print('z value: ', z)
if barcode_names[x] != unique_barcodes[y]:
y = y+1
print('next page')
print(C_numbers[x])
x = x+1
Output:
12
5
7
next page
28
32
13
next page
2
9
>

Going through a DataFrame using .iloc

What I want to do is save part of the dataframe into a list.
I have my DataFrame data_S and when it is printed it looks like this:
data_S
open high low close volume datetime
0 329.30 334.860 327.8800 333.74 5357973.0 1.578290e+12
1 334.26 344.190 330.7100 337.28 9942277.0 1.578377e+12
2 332.40 334.030 329.6000 331.37 8246250.0 1.578463e+12
3 334.95 341.730 332.0500 336.34 8183707.0 1.578550e+12
4 335.56 337.700 329.4548 329.92 7170124.0 1.578636e+12
.. ... ... ... ... ... ...
249 216.36 218.554 214.3650 216.67 10812617.0 1.609308e+12
250 216.24 216.900 212.7000 214.06 10487567.0 1.609394e+12
251 210.00 210.200 202.4911 202.72 21225594.0 1.609740e+12
252 204.74 213.350 204.6000 211.63 19338304.0 1.609826e+12
253 210.22 215.610 209.3400 211.03 16202157.0 1.609913e+12
I want to be able to replicate the code below and change the value of the bolded with a for loop value of nums.
list_of_five_day_range = []
#so then it starts with the first list being the most recent and then in
#[X,Y,Z] Z is the most recent high or is in data_S[253]['high']
list_of_max_value = []
bars = data_S.iloc[-**5**:]['high']
list_of_five_day_range.append(list(bars))
max_value = bars.max()
list_of_max_value.append(max_value)
bars1 = data_S.iloc[**-6:-1**]['high']
list_of_five_day_range.append(list(bars1))
max_value1 = bars1.max()
list_of_max_value.append(max_value1)
max_id = bars.max()
# [X,Y,Z] Z is the most recent with the list at [0] is the most recent data
print(str(list_of_five_day_range) + " this is last 5 days of data")
# with the first number in the list is for the most recent first day high.
print(str(list_of_max_value)+" this is maxium number in last 5 days")
returns
[[218.554, 216.9, 210.2, 213.35, 215.61], [221.68, 218.554, 216.9, 210.2, 213.35]] this is last 5 days of data
[218.554, 221.68] this is maxium number in last 5 days
but in a function and for it to go through the DataFrame. This is what I have so far
def five_day_range(price_history):
for nums in range(len(price_history.index) - 1):
list_of_five_day_range = []
#so then it starts with the first list being the most recent and then [X,Y,Z] Z is the most recent
list_of_max_value = []
bars = price_history.iloc[-5 + int(-nums): int(-nums)]["high"]
list_of_five_day_range.append(bars)
max_value = bars.max()
list_of_max_value.append(max_value)
# print( str(bars)+ " this is the veyr first list of range ")
return list_of_five_day_range, list_of_max_value
However, when I print(five_day_range(data_S)) this is what I get
([0 334.86
1 344.19
Name: high, dtype: float64], [344.19])
I dont understand why it is printing this when the nums value should be going up the DataFrame. This is how I thought the for loop would go through the DataFrame.
enter image description here
I thought it would first append the yellow data then the blue and green, and so on until it hits index[0]/
To answer your first question:
I believe data_S.drop(columns=['high', 'low']) returns another dataframe, which by default requires you to reassign the result into another variable.
With that in mind, you can either do:
data_S = data_S.drop(columns=["high", "low"])
or
data_S.drop(columns=["high", "low"], inplace=True)
UPDATED based on updated question:
Try this, and your list should be returned as expected.
You are defining list_of_five_day_range and list_of_max_value as [] on every iteration of the loop. Hope that makes sense.
def five_day_range(price_history):
list_of_five_day_range = []
list_of_max_value = []
for nums in range(len(price_history.index) - 1):
bars = price_history.iloc[-5 + int(-nums): int(-nums)]["high"]
list_of_five_day_range.append(bars)
max_value = bars.max()
list_of_max_value.append(max_value)
return list_of_five_day_range, list_of_max_value

Changing the values like a switch-case?

I am trying to get the value of "a" like a switch-case. There are only two values for "a" which is either 0 or 18. Let's take 18 as the intial value, when the length of the name is less than or equal to 5 at first name "Devin", the value is "a" is 18 first, and when the length is greater than 5, the value has to switch to 0 and stay 0 till the next length name greater than 5 doesn't show up. The output should be 18,0,0,0,18,0. The program should flip the values only when the name with length greater than 5 appears.
This is what I tried
names = ["Devin","Ashish","Rachi","David","Dohyun","Seonhwa"]
for i in range(len(names)):
#print(len(names[i]))
if len(names[i])<=5:
a =18
else:
a=0
print(a)
names = ["Devin", "Ashish", "Rachi", "David", "Dohyun", "Seonhwa"]
# Pick a start value based on the first name
a = 18 if len(names[0]) <= 5 else 0
print(a)
for name in names[1:]:
if len(name) > 5:
a = 0 if a == 18 else 18
print(a)

Solving knapsack problem using a greedy python algorithm

I'm trying to solve the knapsack problem using Python, implementing a greedy algorithm. The result I'm getting back makes no sense to me.
Knapsack:
The first line gives the number of items, in this case 20. The last line gives the capacity of the knapsack, in this case 524. The remaining lines give the index, value and weight of each item.
20
1 91 29
2 60 65
3 61 71
4 9 60
5 79 45
6 46 71
7 19 22
8 57 97
9 8 6
10 84 91
11 20 57
12 72 60
13 32 49
14 31 89
15 28 2
16 81 30
17 55 90
18 43 25
19 100 82
20 27 19
524
Python code:
import os
def constructive():
knapsack = []
Weight = 0
while(Weight <= cap):
best = max(values)
i = values.index(best)
knapsack.append(i)
Weight = Weight + weights[i]
del values[i]
del weights[i]
return knapsack, Weight
def read_kfile(fname):
with open(fname, 'rU') as kfile:
lines = kfile.readlines() # reads the whole file
n = int(lines[0])
c = int(lines[n+1])
vs = []
ws = []
lines = lines[1:n+1] # Removes the first and last line
for l in lines:
numbers = l.split() # Converts the string into a list
vs.append(int(numbers[1])) # Appends value, need to convert to int
ws.append(int(numbers[2])) # Appends weigth, need to convert to int
return n, c, vs, ws
dir_path = os.path.dirname(os.path.realpath(__file__)) # Get the directory where the file is located
os.chdir(dir_path) # Change the working directory so we can read the file
knapfile = 'knap20.txt'
nitems, cap, values, weights = read_kfile(knapfile)
val1,val2 =constructive()
print ('knapsack',val1)
print('weight', val2)
print('cap', cap)
Result:
knapsack [18, 0, 8, 13, 3, 8, 1, 0, 3]
weight 570
cap 524
Welcome. the reason why your program is giving a weights over the cap limit is because on the final item you are putting in the knapsack, you aren't checking if it can fit in it. To do this just add an if statement, Also you should check if the list of values is empty. Do note that I have append (i+1) since your text file's index is starting at 1 but Python starts it's list index at 0:
def constructive():
knapsack = []
Weight = 0
while(Weight <= cap and values):
best = max(values)
i = values.index(best)
if weights[i] <= cap-Weight:
knapsack.append(i+1)
Weight = Weight + weights[i]
del values[i]
del weights[i]
return knapsack, Weight
The problem is -- in the last step -- the best item you find will exceed the maximum weight. But since you already entered the loop you add it anyway.
In the next iteration you recognize that you are over the cap and stop.
I am not sure how you want to proceed once the next best is too heavy. In case you simple want to stop and not add anything more you can simply modify your constructive to look as follows:
def constructive():
knapsack = []
Weight = 0
while(True):
best = max(values)
i = values.index(best)
if Weight + weights[i] > cap:
break
knapsack.append(i)
Weight = Weight + weights[i]
del values[i]
del weights[i]
return knapsack, Weight

Categories