How to make my code work more efficiently - python-3.x

I made this grade calculator that calculates the grade form my school website. There are some minor flaws that do not affect the code, but does bug me. For example, When I paste the grade from the website, I have to press enter twice, which people who are using my program for the first time get confused with. Also, I want to make it so that the code does not create errors when I press enter without any data given in input.
Not only, these, but I want some feedback on my code and how I can improve them.
This is the code I worked on so far.
class color:
reset = '\\033\[0m'
class fg:
green = '\\033\[32m'
orange = '\\033\[33m'
\#getting input from user
def multi_input():
try:
while True:
data=input(color.fg.orange)
if not data: break
yield data
except KeyboardInterrupt:
return
restart=1
while restart!="x":
score = \[\]
percent = \[\]
add = \[\]
print(color.fg.green + "Enter Grade" + color.reset)
data = 0
data = list(multi_input())
#filter data into percent and score
for i in range(3, len(data),4):
data[i] = data[i].split('\t')
try:
percent.append(data[i][3])
score.append(data[i][4])
except IndexError:
result = 0
#take out ungraded values
percent = [value for value in percent if value != '']
score = [value for value in score if value != '']
#refine percent data
for i in range(len(percent)):
try:
percent[i] = percent[i].replace('%', '')
percent[i] = float(percent[i])
except ZeroDivisionError:
result = 0
#refine score data
for i in range(len(score)):
score[i] = score[i].split('/')
for j in range(len(score[i])):
score[i][j] = float(score[i][j])
try:
score[i] = score[i][0]/score[i][1]*100
except ZeroDivisionError:
result = 0
#amount of assignments
print()
print(color.fg.green + "graded assignments: ", len(score))
#calculation
for i in range(len(score)):
add.append(score[i]*percent[i]/100)
print(color.fg.green + "Percentage: ", f"{sum(add)/sum(percent)*100:05.2f}" + color.reset)
restart = input(color.fg.green + "press any key to start again, or x to exit.")
print()
This is a sample grade copied from my school website so that you can test my code out.
Nov
02
Projects & Labs
4.2 If statements & 4.3 Comparison A 1% 100/100 11/2/22
Nov
02
Quiz
4.2 If statements & 4.3 Comparison Quizzes A 0.4% 100/100 11/2/22
Oct
31
Projects & Labs
4.1 Booleans Labs A 1% 100/100 10/31/22
Oct
31
Quiz
4.1 Boolean Quiz A 0.4% 100/100 10/31/22
Oct
24
Exams & Tests
Python Console & Interaction Module Test A 12.5% 200/200 Test 18/20 Programming: 100(Extra 10 points Extra credit) 10/24/22
Oct
24
Homework
Study for Python Console & Interaction Quiz & Programming Test: Ungraded (Ungraded)
Oct
21
Projects & Labs
3.6 Comments Quiz & Lab C 1% 75/100 Quiz = 1/2 10/26/22
Oct
21
Projects & Labs
3.5 String Operators Labs A 2% 200/200 no screenshot of recipe 10/24/22

Related

The logical error or test case error in python

Handling Expection
The full question is of Hackerrank. I have passed all the test cases but one test case is failing. I don't know why. Logic is correct. Please help me
test case in given question
*
4500(membership fee)
3(number of installments)
Welcome boy(name)
*
my code is
def Library(memberfee, installment, book):
if(installment > 3):
print("Maximum Permitted Number of Installments is 3")
else:
if(installment == 0):
print("Number of Installments cannot be Zero.")
else:
print("Amount per Installment is {}".format(memberfee/installment))
ListOfBooks = ["philosophers stone", "chamber of sec rets", "prisoner of azkaban", "goblet of fire", "order of phoenix", "half blood price", "deathly hallows 1", "deathly hallows2"]
book = book.lower()
if book in ListOfBooks:
print("It is available in this section")
else:
print("No such book exists in this section")
if __name__ == '__main__':
memberfee = int(input())
installment = int(input())
book = input()
try:
Library(memberfee,installment,book)
except ZeroDivisionError as e:
print(e)
except ValueError as e:
print(e)
except NameError as e:
print(e)
**i think the problem may be here
print("Amount per Installment is {}".format(memberfee/installment))
**
The question is.....
*Library
This exception handling scenario deals with the exceptional cases that arise in a typical library interface of a Town library.
O
1
About the Library Interface
This is a typical interface provided in the library, which takes 3 inputs from the library members, sequentially. They are:
memberfee - Membership fee for the library for the next financial year, which can be paid in installments.
installment - Number of installments chosen to pay the Membership fee. 3. book- Name of the book the member looks for in the 'Harry Potter' Section.
23
24
25
26
27
28
29
30
Note
All the above inputs except 'book' are Integers.
Write the function definition as follows, for the function 'Library', that takes all the above 3 inputs as its parameters:
The maximum permitted number of installments to pay the annual membership fee is '3'.
Raise ValueError exception if the input for the number of installments is greater than '3' and Print a Message. The message to the user must be, "Maximum Permitted Number of Installments is 3", The amount per installment is calculated by dividing the Membership fee by the number of installments. 2. Raise ZeroDivision Error exception if the input for the number of installments is equal to '0' and Print a Message. The message to the user must be, "Number of Installments cannot be Zero." else
1
#!/bin/python
10
11
def Library (
if(insta
prin
else:
if(
els
(memberfee
sec rets",
phoenix",
hallows 2"1
Print the amount per installment as "Amount per Installment is 3000.0".
12
13
The 'Harry Potter' book section contains the following books only:
14
ALL
1
15
philosophers stone
16
. chamber of secrets
17
• prisoner of azkaban
18
19
• goblet of fire
• order of phoenix
half blood prince
deathly hallows 1
21
23
20
24
• deathly hallows 2*
def Library(memberfee,installment,book):
# Write your code here
#print(memberfee)
#print(installment)
#print(book)
if installment > 3:
raise(ValueError("Maximum Permitted Number of Installments is 3"))
if installment == 0:
raise(ZeroDivisionError("Number of Installments cannot be Zero."))
else:
print ("Amount per Installment is ", memberfee / installment)
if book == 'philosophers stone' or book == 'Chamber of Secrets' or book == 'prisoner of azkaban' or book == 'Goblet of Fire' or book == 'order of phoenix' or book == 'Half Blood Prince' or book == 'Deathly Hallows 1' or book == 'deathly hallows 2':
print ("It is available in this section")
else:
raise(NameError("No such book exists in this section"))
Your ListofBooks contains some grammatical errors in the names of the books. Maybe that's what caused the error.
In my opinion, it is just a name not matching with listofbooks.
Please try to check all the book names from listofbooks.

Convert user input to time which changes boolean value for the duration entered?

I'm working on this side project game to grasp python better. I'm trying to have the user enter the amount of time the character has to spend busy, then not allow the user to do the same thing until they have completed the original time entered. I have tried a few methods with varying error results from my noob ways. (timestamps, converting input to int and time in different spots, timeDelta)
def Gold_mining():
while P.notMining:
print('Welcome to the Crystal mines kid.\nYou will be paid in gold for your labour,\nif lucky you may get some skill points or bonus finds...\nGoodluck in there.')
print('How long do you wish to enter for?')
time_mining = int(input("10 Gold Per hour. Max 8 hours --> "))
if time_mining > 0 and time_mining <= 8:
time_started = current_time
print(f'You will spend {time_mining} hours digging in the mines.')
P.gold += time_mining * 10
print(P.gold)
P.notMining = False
End_Time = (current_time + timedelta(hours = 2))
print(f'{End_Time} time you exit the mines...')
elif time_mining > 8:
print("You can't possibly mine for that long kid, go back and think about it.")
else:
print('Invalid')
After the set amount of time i would like for it to change the bool value back to false so that you can mine again.
"Crystal Mining" is mapped to a different key for testing so my output says "Inventory" but would say "Crystal Mining" when it works properly and currently looks like this:
*** Page One ***
Intro Page
02:15:05
1 Character Stats
2 Rename Character
3 Inventory
4 Change Element
5 Menu
6 Exit
Num: 3
Welcome to the Crystal mines kid.
You will be paid in gold for your labour,
if lucky you may get some skill points or bonus finds...
Goodluck in there.
How long do you wish to enter for?
10 Gold Per hour. Max 8 hours --> 1
You will spend 1 hours digging in the mines.
60
Traceback (most recent call last):
File "H:\Python ideas\input_as_always.py", line 176, in <module>
intro.pageInput()
File "H:\Python ideas\input_as_always.py", line 45, in pageInput
self.pageOptions[pInput]['entry']()
File "H:\Python ideas\input_as_always.py", line 134, in Gold_mining
End_Time = (current_time + timedelta(hours = 2))
TypeError: can only concatenate str (not "datetime.timedelta") to str

Python 3 formatting issue with '$'

I just started learning Python this week and I'm having an issue with some line formatting. I am trying to insert a '$' along with the calculated values, I've tried to insert the '$' with a new {} set, as well as here {{$:>{}.2f}} (based on Google search suggestions), however I keep getting errors.
I'm using Google Collab to run the code.
def budget_calc(money, rent, food, phone, gas, extra_income):
width = 35
price_width = 10
item_width = width - price_width
income = sum(weekly_income) + extra_income
expenses = sum(credit_cards) + rent + phone + food + gas + utilities
after_tax =income*0.84
#after_tax_instr = str(after_tax)
gross = 'Money before tax:' #+ str(income)
post_tax= 'Post tax income:' #+after_tax_instr
tax_payment ='Taxes due:' #+str(income*.16)
savings = after_tax - expenses
total = 'Money left over:' #+'$'+str(savings)
expense_total = 'Total expenses' #+str([expenses])
line = "{{:{}}} {{:>{}.2f}}".format(item_width, price_width)
print(line.format(gross, income))
print(line.format(tax_payment, (income*0.16)))
print(line.format(post_tax, after_tax))
print(line.format(expense_total, expenses))
print(line.format(total, savings))
The output I get is:
Money before tax: 3300.00
Taxes due: 528.00
Post tax income: 2772.00
Total expenses 2190.00
Money left over: 582.00
Days until my Mac: 44.36
I would appreciate any pointers in the right direction.
I think the error it throws will be keyerror and it because of the messy string format
def budget_calc(money, rent, food, phone, gas, extra_income):
width = 35
price_width = 10
item_width = width - price_width
income = sum(weekly_income) + extra_income
expenses = sum(credit_cards) + rent + phone + food + gas + utilities
after_tax =income*0.84
#after_tax_instr = str(after_tax)
gross = 'Money before tax:' #+ str(income)
post_tax= 'Post tax income:' #+after_tax_instr
tax_payment ='Taxes due:' #+str(income*.16)
savings = after_tax - expenses
total = 'Money left over:' #+'$'+str(savings)
expense_total = 'Total expenses' #+str([expenses])
# You can specify the width integer instead of formating
line = "{0:<25} ${1:.2f}"
print(line.format(gross, income))
print(line.format(tax_payment, (income*0.16)))
print(line.format(post_tax, after_tax))
print(line.format(expense_total, expenses))
print(line.format(total, savings))
Note : since weekly_income and credit_cards are not provided i just
removed it from script in order to check the output
When `budget_calc(33000,500,10,100,152,510)` this is called the output
Output :
Money before tax: $33510.00
Taxes due: $5361.60
Post tax income: $28148.40
Total expenses $762.00
Money left over: $27386.40
Python 3.6+ String interpolation is recommended way of string formatting because of its high readabililty.
The best way would be:
print(f'Money before tax: {income}')
print(f'Taxes due:{income*0.16}')
print(f'Post tax income: {after_tax}')
print(f'Total expenses: {expenses}')
print(f'Money left over :{savings}')
But if you want to use $ String Formatting only , the you should try the answer by DaVinci

Parsing heterogenous data from a text file in Python

I am trying to parse raw data results from a text file into an organised tuple but having trouble getting it right.
My raw data from the textfile looks something like this:
Episode Cumulative Results
EpisodeXD0281119
Date collected21/10/2019
Time collected10:00
Real time PCR for M. tuberculosis (Xpert MTB/Rif Ultra):
PCR result Mycobacterium tuberculosis complex NOT detected
Bacterial Culture:
Bottle: Type FAN Aerobic Plus
Result No growth after 5 days
EpisodeST32423457
Date collected23/02/2019
Time collected09:00
Gram Stain:
Neutrophils Occasional
Gram positive bacilli Moderate (2+)
Gram negative bacilli Numerous (3+)
Gram negative cocci Moderate (2+)
EpisodeST23423457
Date collected23/02/2019
Time collected09:00
Bacterial Culture:
A heavy growth of
1) Klebsiella pneumoniae subsp pneumoniae (KLEPP)
ensure that this organism does not spread in the ward/unit.
A heavy growth of
2) Enterococcus species (ENCSP)
Antibiotic/Culture KLEPP ENCSP
Trimethoprim-sulfam R
Ampicillin / Amoxic R S
Amoxicillin-clavula R
Ciprofloxacin R
Cefuroxime (Parente R
Cefuroxime (Oral) R
Cefotaxime / Ceftri R
Ceftazidime R
Cefepime R
Gentamicin S
Piperacillin/tazoba R
Ertapenem R
Imipenem S
Meropenem R
S - Sensitive ; I - Intermediate ; R - Resistant ; SDD - Sensitive Dose Dependant
Comment for organism KLEPP:
** Please note: this is a carbapenem-RESISTANT organism. Although some
carbapenems may appear susceptible in vitro, these agents should NOT be used as
MONOTHERAPY in the treatment of this patient. **
Please isolate this patient and practice strict contact precautions. Please
inform Infection Prevention and Control as contact screening might be
indicated.
For further advice on the treatment of this isolate, please contact.
The currently available laboratory methods for performing colistin
susceptibility results are unreliable and may not predict clinical outcome.
Based on published data and clinical experience, colistin is a suitable
therapeutic alternative for carbapenem resistant Acinetobacter spp, as well as
carbapenem resistant Enterobacteriaceae. If colistin is clinically indicated,
please carefully assess clinical response.
EpisodeST234234057
Date collected23/02/2019
Time collected09:00
Authorised by xxxx on 27/02/2019 at 10:35
MIC by E-test:
Organism Klebsiella pneumoniae (KLEPN)
Antibiotic Meropenem
MIC corrected 4 ug/mL
MIC interpretation Resistant
Antibiotic Imipenem
MIC corrected 1 ug/mL
MIC interpretation Sensitive
Antibiotic Ertapenem
MIC corrected 2 ug/mL
MIC interpretation Resistant
EpisodeST23423493
Date collected18/02/2019
Time collected03:15
Potassium 4.4 mmol/L 3.5 - 5.1
EpisodeST45445293
Date collected18/02/2019
Time collected03:15
Creatinine 32 L umol/L 49 - 90
eGFR (MDRD formula) >60 mL/min/1.73 m2
Creatinine 28 L umol/L 49 - 90
eGFR (MDRD formula) >60 mL/min/1.73 m2
Essentially the pattern is that ALL information starts with a unique EPISODE NUMBER and follows with a DATE and TIME and then the result of whatever test. This is the pattern throughout.
What I am trying to parse into my tuple is the date, time, name of the test and the result - whatever it might be. I have the following code:
with open(filename) as f:
data = f.read()
data = data.splitlines()
DS = namedtuple('DS', 'date time name value')
parsed = list()
idx_date = [i for i, r in enumerate(data) if r.strip().startswith('Date')]
for start, stop in zip(idx_date[:-1], idx_date[1:]):
chunk = data[start:stop]
date = time = name = value = None
for row in chunk:
if not row: continue
row = row.strip()
if row.startswith('Episode'): continue
if row.startswith('Date'):
_, date = row.split()
date = date.replace('collected', '')
elif row.startswith('Time'):
_, time = row.split()
time = time.replace('collected', '')
else:
name, value, *_ = row.split()
print (name)
parsed.append(DS(date, time, name, value))
print(parsed)
My error is that I am unable to find a way to parse the heterogeneity of the test RESULT in a way that I can use later, for example for the tuple DS ('DS', 'date time name value'):
DATE = 21/10/2019
TIME = 10:00
NAME = Real time PCR for M tuberculosis or Potassium
RESULT = Negative or 4.7
Any advice appreciated. I have hit a brick wall.

Printing list in different columns

I am quite new to Python and I am now struggling with printing my list in columns. It prints my lists in one columns only but I want it printed under 4 different titles. I know am missing something but can't seem to figure it out. Any advice would be really appreciated!
def createMyList():
myAgegroup = ['20 - 39','40 - 59','60 - 79']
mygroupTitle = ['Age','Underweight','Healthy','Overweight',]
myStatistics = [['Less than 21%','21 - 33','Greater than 33%',],['Less than 23%','23 - 35','Greater than 35%',],['Less than 25%','25 - 38','Greater than 38%',]]
printmyLists(myAgegroup,mygroupTitle,myStatistics)
return
def printmyLists(myAgegroup,mygroupTitle,myStatistics):
print(': Age : Underweight : Healthy : Overweight :')
for count in range(0, len(myAgegroup)):
print(myAgegroup[count])
for count in range(0, len(mygroupTitle)):
print(mygroupTitle[count])
for count in range(0, len(myStatistics)):
print(myStatistics[0][count])
return
createMyList()
To print data in nice columns is nice to know Format Specification Mini-Languag (doc). Also, to group data together, look at zip() builtin function (doc).
Example:
def createMyList():
myAgegroup = ['20 - 39','40 - 59','60 - 79']
mygroupTitle = ['Age', 'Underweight','Healthy','Overweight',]
myStatistics = [['Less than 21%','21 - 33','Greater than 33%',],['Less than 23%','23 - 35','Greater than 35%',],['Less than 25%','25 - 38','Greater than 38%',]]
printmyLists(myAgegroup,mygroupTitle,myStatistics)
def printmyLists(myAgegroup,mygroupTitle,myStatistics):
# print the header:
for title in mygroupTitle:
print('{:^20}'.format(title), end='')
print()
# print the columns:
for age, stats in zip(myAgegroup, myStatistics):
print('{:^20}'.format(age), end='')
for stat in stats:
print('{:^20}'.format(stat), end='')
print()
createMyList()
Prints:
Age Underweight Healthy Overweight
20 - 39 Less than 21% 21 - 33 Greater than 33%
40 - 59 Less than 23% 23 - 35 Greater than 35%
60 - 79 Less than 25% 25 - 38 Greater than 38%

Resources