how to search user entered value in a list? [closed] - python

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 months ago.
This post was edited and submitted for review 8 months ago and failed to reopen the post:
Original close reason(s) were not resolved
Improve this question
(s213,bill,72,59,45)
(s214,john,88,70,80)
(s215,anne,52,61,44)
(s216,sliva,44,50,35)
above values in the brackets are the marks.txt
and using below code it can convert in to a list
file=open('marks.txt','r')
marks=file.readlines()
for a in marks:
x=a.split(',')
print(x)
I want to user to enter wished student number(s213) and display the student name and the average

You probably want to use a nested dictionary. Here, each key is a student number and each value is another dictionary that stores the student's name and scores.
Code:
students = {"s213": {"name": "bill", "scores": [72, 59, 45]},
"s214": {"name": "john", "scores": [88 , 70, 80]},
"s216": {"name": "sliva", "scores": [44, 50, 35]}}
student_number = input("Please enter the student number: ")
print("Name: " + students[student_number]["name"])
grades = students[student_number]["scores"]
print("Average grade: " + str(sum(grades) / len(grades)))
Output:
Please enter the student number:
s214
Name: john
Average grade: 79.33333333333333

use pandas for loading a csv (what im assuming the format for your data is) and for adding an 'average' column for easier getting
tmp.csv:
student_id,name,grade1,grade2,grade3
s213,bill,72,59,45
s214,john,88,70,80
s215,anne,52,61,44
s216,sliva,44,50,35
code
import pandas as pd
# load csv
df = pd.read_csv('tmp.csv')
df['average'] = df.mean(axis=1)
print(df)
search_name = input('enter student name to get an average for: ')
print(df['average'][df['name'] == search_name])
df printed:
student_id name grade1 grade2 grade3 average
0 s213 bill 72 59 45 58.666667
1 s214 john 88 70 80 79.333333
2 s215 anne 52 61 44 52.333333
3 s216 sliva 44 50 35 43.000000
result from search
enter student name to get an average for: bill
0 58.666667
Name: average, dtype: float64
NOTE: the mean method call used to get averages will try to average ALL elements of the row. string's can't be averaged so they're ignored and instead all numbers are averaged. if your data has numbers included that shouldn't be averaged, the logic will need to change

Related

Looking for any matching terms from file

I have a file that has a large list of Countries, years, and ages of living expectancies. I cannot figure out how to make sure the user is only allowed to input a year that actually exists. After figuring this out, I will need to call only those years (with corresponding country name, code, and living expectancies. How can I do this?
import pathlib
cwd = pathlib.Path(__file__).parent.resolve()
data_file = f'{cwd}/life-expectancy.csv'
with open(data_file) as f:
while True:
user_year = input('Enter the year of interest: ')
for lines in f:
cat = lines.strip().split(',')
country = cat[0]
code = cat[1]
year = cat[2]
age = cat[3]
if any( [year in user_year for year in cat[2]] ):
print(f'Your year is {user_year}. That is one of our known years.')
print(year)
print()
continue
else:
print('Please enter a valid year (1751-2019)')
print('test')
Solution 1
If all the dates from 1751 to 2019 are in your file, then you don't need to read your file to check that, you can simply do that:
# Ask the user for the year
prompt_text = "Enter the year of interest: "
user_year = int(input(prompt_text))
while not 1751 <= user_year <= 2019:
print("Please enter a valid year (1751-2019)")
user_year = int(input(prompt_text))
After that you can read your file and store the data only if the years are matching:
# Get the data for the asked year
# Example of final data: [("France", "FR", 45), ("Espagne", "ES", 29)]
data = []
with open(data_file, "r", encoding="utf-8") as file:
for line in file:
country, code, year, age = line.strip().split(",")
if int(year) == user_year:
data.append((country, code, int(age)))
Solution 2
If you really need to check the year in your file, e.g. because 1845 is not in it, then read the file once and store all the data in a dictionary indexed by the year and return the data of the asked year if it is present:
data = {}
with open(data_file, "r", encoding="utf-8") as file:
for line in file:
country, code, year, age = line.strip().split(",")
year = int(year)
if year in data:
data[year].append((country, code, int(age)))
else:
data[year] = [(country, code, int(age))]
prompt_text = "Enter the year of interest: "
user_year = int(input(prompt_text))
while user_year not in data:
print("The year is not present in the file")
user_year = int(input(prompt_text))
print(data[user_year])
One could use DataFrames to handle such cases. To know more information on dataframe, take a look into Pandas.DataFrame
To select specific column contents from the dataframe: df[[<col_1>, <col_2>]]
Considering the data fetched could produce the following.
import pandas as pd
df = pd.read_csv("Life Expectancy Data.csv")
year = int(input("Enter the year of interest: "))
df = df[["Country", "Year", "Life expectancy "]]
if year in df["Year"].values:
print(f'Your year is {year}. That is one of our known years.')
display(df.loc[df["Year"] == year])
else:
print("Please enter a valid year (2000-2015)")
Your question includes two questions.
1. Question and answer
I cannot figure out how to make sure the user is only allowed to
input a year that actually exists.
Your range of accepted years is 1751-2019. You could create a list with these integers and check that the user input is within that range. E.g.
allowed_answers = list(range(1751, 2019, 1))
There are multiple ways to check the user input and the one you want to use depends on how you want the user interaction to be. Here are few examples:
1.Stop the program immediately if user input is invalid
user_year = input('Enter the year of interest: ')
allowed_answers = list(range(1751, 2019, 1))
assert user_year in allowed_answers, "User input is invalid"
...
2.Ask user to input number until it is accepted
allowed_answers = list(range(1751, 2019, 1))
user_year = 0
while int(user_year) not in allowed_answers:
print('Please enter a valid year (1751-2019)')
user_year = input('Enter the year of interest: ')
3.Combining the two solutions to have a limit of prompts.
allowed_answers = list(range(1751, 2019, 1))
user_year = 0
for i in range(0,5):
print('Please enter a valid year (1751-2019)')
user_year = input('Enter the year of interest: ')
if int(user_year) in allowed_answers:
input_valid = True
break
else:
input_valid = False
assert input_valid, "No correct input after five tries."
Note that all these solutions only handle inputs that can be converted into integer. To go around that, you might need some try... except clauses for the data transformation from string to integer, or transform the list items of allowed_answers into strings.
2. Question and answer
After figuring this out, I will need to call only those years (with corresponding country name, code, and living expectancies. How can I do this?
I would read the file only once a make it into a dictionary. Then you only need to do the indexing once and search from there as long as your program is running. See https://docs.python.org/3/tutorial/datastructures.html#dictionaries .
With these suggestions I would do the data reading and transformation into dictionary outside (and before) your while loop.

How to match input data and a data in df, for loop minus

I want the input str to match with str in file that have fix row and then I will minus the score column of that row
1!! == i think this is for loop to find match str line by line from first to last
2!! == this is for when input str have matched it will minus score of matched row by 1.
CSV file:
article = pd.read_csv('Customer_List.txt', delimiter = ',',names = ['ID','NAME','LASTNAME','SCORE','TEL','PASS'])
y = len(article.ID)
line=article.readlines()
for x in range (0,y): # 1!!
if word in line :
newarticle = int(article.SCORE[x]) - 1 #2!!
print(newarticle)
else:
x = x + 1
P.S. I have just study python for 5 days, please give me a suggestion.Thank you.
Since I see you using pandas, I will give a solution without any loops as it is much easier.
You have, for example:
df = pd.DataFrame()
df['ID'] = [216, 217]
df['NAME'] = ['Chatchai', 'Bigm']
df['LASTNAME'] = ['Karuna', 'Koratuboy']
df['SCORE'] = [25, 15]
You need to do:
lookfor = str(input("Enter the name: "))
df.loc[df.NAME == lookfor, 'SCORE']-= 1
What happens in the lines above is, you look for the name entered in the NAME column of your dataframe, and reduce the score by 1 if there is a match, which is what you want if I understand your question.
Example:
Now, let's say you are looking for a person called Alex with the name, since there is no such person, you must get the same dataframe back.
Enter the name: Alex
ID NAME LASTNAME SCORE
0 216 Chatchai Karuna 25
1 217 Bigm Koratuboy 15
Now, let's say you are looking for a person called Chatchai with the name, since there is a match and you want the score to be reduced, you will get:
Enter the name: Chatchai
ID NAME LASTNAME SCORE
0 216 Chatchai Karuna 24
1 217 Bigm Koratuboy 15

I wrote a code for 2 or 3 inputs but for many inputs what should i do [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
print("Store Room Stock Category")
print("")
print("")
Stockmachinary1 = input("Enter the stock material name:")
Stockmachinary1price=int(input("Enter the stock material price:"))
Stockmachinary2=input("Enter the stock material name:")
Stockmachinary2price=int(input("Enter the stock material price:"))
Stockmachinary3=input("Enter the stock material name:")
Stockmachinary3price=int(input("Enter the stock material price:"))
Totalstockprice=Stockmachinary1price+Stockmachinary1price+Stockmachinary3price
import pandas as pd
stock = pd.DataFrame({"stock":[Stockmachinary1,Stockmachinary2,Stockmachinary3,"totalcoststock"],\
"price":[Stockmachinary1price,Stockmachinary2price,Stockmachinary1price,Totalstockprice]})
stock=stock[["stock","price"]]
stock
Totalstockprice
If you talking about not write too many codes, I think you should use loops, and for-loop like below:
print("Store Room Stock Category")
print("")
print("")
StockmachinaryNames = []
StockmachinaryPrice = []
counts = int(input("Enter the stock material you want input:"))
for i in range(counts):
Name = input("Enter the stock material name:")
Price=int(input("Enter the stock material price:"))
StockmachinaryNames.append(Name)
StockmachinaryPrice.append(Price)
TotalstockPrice = sum(StockmachinaryPrice)
StockmachinaryNames.append("totalcoststock")
StockmachinaryPrice.append(TotalstockPrice)
import pandas as pd
stock = pd.DataFrame({"stock":StockmachinaryNames,\
"price":StockmachinaryPrice})
stock=stock[["stock","price"]]
print(stock)
print(TotalstockPrice)
But if you talking about bach data input, I think you may need csv or other file format for input. And pandas work well with it. there is the help page:
http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html

python for loop issue

I currently have this as an assignment. I have written the code below, but there seems to be an issue as the calculations keep on adding. Is there a way to restart the for loop?
There are 7 employees. Write a program with nested loops, to ask the yearly salary of each employee for 5 years. Your program should keep track of the highest salary, lowest salary, and calculate the average salary of each employee. After you collect each employees data, display the highest salary, lowest salary, and average salary for that employee.
totalsalary = 0
salaryhigh = 0
salarylow = 10000000
employee = 0
for employee in range(1,4):
print("Please enter the 5 year salaries of Employee#",employee,":")
for year in range(1,6):
salary = int(input('Enter you salary:'+""))
totalsalary = totalsalary + salary
if(salary > salaryhigh):
salaryhigh = salary
if(salary < salarylow):
salarylow = salary
avesalary = totalsalary/5
print('Total Salary entered for 5 years for Employee#',employee,':',totalsalary)
print("Average is:",avesalary)
print("Highest Salary entered is:",salaryhigh)
print("Lowest Salary entered is:",salarylow)
print("------------------------------------")
Your first three lines should be run for each employee, so they should be inside the outer for loop. The fourth line doesn't really do anything: your for-loop resets the employee number. Also, your for-loop does only three employees, but you state that there are seven employees. It's generally recommended that you set the number of employees at the beginning and then use that in the following code, so it's clear what the number represents and it's easier to keep track of and change the number. E.g.
number_of_employees = 7
for employee in range(0,number_of_employees):
...

How can i remove the commas between words and make them go under each subheading [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
my python code so far is:
list=("Member ID, Surname, Year joined, Nights booked, Membership status, Points balance")
f = open("SampleData2017.txt")
print(list)
for surname in f.readlines():
print(surname)
however when i run it the items are only seperated by commas and not under each subheading
i want it to look like:
MemberID Surname Year joined Membershipstatus Nightsbooked Points balance
Gri33415 Griffiths 2015 Gold 35 40000
Smi22316 Smith 2016 Silver 3 7500
how would i fix this? as simple as possible please
I guess you can use python built in csv module to achieve what you want
Edit 1:
Observe headers is assigned initially as string and then converted list
added ljust to each items to give an idea how this can be achieved, but definitely not the exact alignment the way you want.
import csv
headers="Member ID, Surname, Year joined, Nights booked, Membership status, Points balance"
headers = headers.split(',')
print ('\t'.join(x.ljust(5) for x in headers))
with open('WorkingDirectory\stars.csv', 'r') as mycsv:
rows = csv.reader(mycsv)
for row in rows:
print ('\t'.join(x.ljust(15) for x in row))
Original Answer:
import csv
headers=["Member ID, Surname, Year joined, Nights booked, Membership status, Points balance"]
print ('\t'.join(headers))
with open('SampleData2017.txt', 'r') as mycsv:
rows = csv.reader(mycsv)
for row in rows:
print ('\t'.join(row))
Output:
Member ID, Surname, Year joined, Nights booked, Membership status, Points balance
Gri33415 Griffiths 2015 Gold 35 40000
Smi22316 Smith 2016 Silver 3 7500
Sounds like you have a list of headers, and a table full of data you're pulling from SampleData2017.txt. There's a third-party module called tabulate that I use a lot for this because it keeps me from having to write a bunch of code for a simple task.
Install it from pypi using pip on your command line.
$ pip install tabulate
or on Python3
$ pip3 install tabulate
Then write code:
import tabulate
headers = map(str.strip, "Member ID, Surname, Year joined, Nights booked, Membership status, Points balance".split(","))
# or just format it yourself:
headers = ("Member ID", "Surname", "Year joined", "Nights booked",
"Membership status", "Points balance")
with open("SampleData2017.txt") as f:
# you never say how each row is split into fields, so I'm assuming here
# that it's comma-separated and calling str.split(",") on each
table = tabulate.tabulate((line.split(",") for line in f), headers=headers)
With my sample data here, the output is:
>>> headers = ("one", "two", "three")
>>> data = [(1, 2, 3), (4, 5, 6), (7, 8, 9)]
>>> print(tabulate.tabulate(data, headers=headers))
one two three
----- ----- -------
1 2 3
4 5 6
7 8 9

Categories

Resources