How To Print Strings Between Integer Ranges - Python 3 - python

I'm very new to Python and programming in general, so excuse me if the code is terrible and the problem rather easy to solve.
I have written code to allow a user to have employee data printed based on 3 different inputs, which they are allowed to choose from.
The options the user has available to them are to pick employees based on their payroll number; a minimum and maximum salary range; their job title.
I made two functions for the formatting. The first one turns the lines of the text file into lists, then the second function grabs those individual lists and formats them.
Then the code requests the user to input the file name. If the file cannot be found, they get to try again. If it is correct, the file is loaded and then runs through the functions to print out a neat table.
Then the user is asked what method they want to choose from to select specific employees. They are given 4 options, 3 are mentioned at the start and the fourth is to just end the program.
I managed to successfully get the first option to print out the employees without hassle, as is the same for the fourth option to end the program. I almost have the third one completed, I just need to find a way to print the name without a comma. My problem resides within the second option: how do I print the employees and their details if they fall between the minimum and maximum salary ranges entered by the user if the range isn't an integer since it has to include a '£' sign?
Here's the code. It's the biggest chunk in the program because I just have no clue how to make it work properly -
def detailsPrint(field) : #takes tuple and prints
print("{:30}" "{:6}" "{:15}" "{:7}".format(field[3] + ", " + field[4], field[0], field[2], "£" + field[1]))
if display == 2 :
maxSalary = "£1000000"
minpay = input("Enter the minimum pay : ")
maxpay = input("Enter the maximum pay : ")
if len(minpay) and len(maxpay) < maxSalary :
for s in employeeList :
if s[1] >= minpay :
detailsPrint(s)
The outcome should be something like (example) Simpson, Bart 12345 Consultant £55000 if the minpay were to be £50000 and maxpay £60000
edit: Managed to get it working. Here's the code
if display == 2 :
x = False
maxSalary = 1000000
minpay = int(input("Enter the minimum pay: "))
maxpay = int(input("Enter the maximum pay: "))
if int(minpay) > int(maxSalary) or int(maxpay) > int(maxSalary) :
x = False
print("No employees earn over £1000000. Try again.")
if int(minpay) or int(maxpay) < int(maxSalary) :
for s in employeeList :
if int(s[1]) >= minpay and int(s[1]) <= maxpay :
detailsPrint(s)
x = True
if x == False :
print("No employees could be found within that range. Try again")
print("\n")

Simplest solution: don't ask for the £ char ;-)
A solution that work with your requirement is to change the line
if len(minpay) or len(maxpay) > maxSalary :
with something like
if int(minpay[1:]) > int(maxSalary[1:]) or int(maxpay[1:]) > int(maxSalary[1:]) :
which check the numeric value of the strings (your condition seems wrong anyway to me)

You could replace all "£" signs to "" in a string.
YourString.replace("£", "")

Related

Python Program counting and list question

I made a Python program to repeat the number of internships that I applied for, BUT I need it to store the amount I add so that I can ask it later how many I applied for, rather than me having to enter a number every time. Also, I want it to be able to update if the number of internships I applied for changes, I will input the new number of internships manually. How can I change my program to do that? Please take a look thanks
print("Welcome back, Ryan")
internships = {}
asking_ryan = True
amount = input("Enter how many internships you have applied for: ")
amount = int(amount)
if amount > 1:
print("You have applied for: " + str(amount) + " internship(s)")
str(amount)
if amount < 1:
print("Error! you cannot apply for 0 internships!")
if amount == 1:
print("You have applied for: " + str(amount) + " internship")
Program output:
Welcome back, Ryan.
Enter how many internships you have applied for: 2
You have applied for: 2 internship(s)
I saw your question. I kind of understand it.
You want to be able to update the internships you have done so you don't have to always rerun the program so it counts your internship?
You might have to use some files for that, should be simple!
First, you can make a file called opens.txt and add a 0 to the file that tracks how many times you opened that program. When you run the program do this:
opens = open("opens.txt", w+)
open_count = int(opens.read())
opens.write(open_count + 1)
if open_count == 1:
amount = input("Enter how many internships you have applied for: ")
... # Other Code
Then make a file called something like internships.txt where it will store how many internships you currently have, default it to 0.
internships = open("internships.txt", w+)
internship_count = int(internships.read())
print("You currently have applied to {} internships since last time...".format(internship_count)
new_internships = input("How many new internships have you applied for? ")
internships.write(internship_count + new_internships)
I think this should help? Haven't used files in a long time. Next time please phrase your question a bit better.

Can someone explain why var = input() in python doesn't work?

You want to know your grade in Computer Science, so write a program
that continuously takes grades between 0 and 100 to standard input
until you input "stop", at which point it should print your average to
standard output.
NOTE: When reading the input, do not display a prompt for the user.
Use the input() function with no prompt string. Here is an example:
grade = input()
grade = input()
count = 0
sum = 0
while grade != "stop":
grade = input()
sum += int(grade)
count += 1
print(sum / count)
Please dont solve it for me, but if you can point out why setting grade as "input()" doesnt work
You input a line as the first operation and then correctly enter the loop only if it isn't "stop".
However, that should then be the value you use for summing rather than immediately asking the user for another value. In your current code, if the user enters "stop", there is no check before attempting to treat it as a number.
So, if you don't want a solution, I'd suggest you stop reading at this point :-)
Couldn't resist, could you? :-)
The solution is to simply move the second input call to the bottom of the loop, not the top. This will do the check on the last thing entered, be that before the loop starts or after the value has been checked and accumulated.
In addition, your print statement is inside the loop where it will print after every entry. It would be better
There's other things you may want to consider as well, such as:
moving your print outside the loop since currently you print a line for every input value. You'll also have to catch the possibility that you may divide by zero (if the first thing entered was "stop").
handling non-numeric input that isn't "stop";
handling numeric input outside the 0..100 range.
Don't use this since you're trying to educate yourself (kudos on you "please don't solve it for me" comment by the way) and educators will check sites like SO for plagiarism, but a more robust solution could start with something like:
# Init stuff needed for calculating mean.
(count, total) = (0, 0)
#Get first grade, start processing unless stop.
grade = input()
while grade != "stop":
# Convert to number and accumulate, invalid number (or
# out of range one) will cause exception and not accumulate.
try:
current = int(grade)
if current < 0 or current > 100:
throw("range")
# Only reaches here if number valid.
total += int(grade)
count += 1
except:
print(f'Invalid input: {grade}, try again')
# Get next grade and check again at loop start.
grade = input()
# If we entered at least one valid number, report mean.
if count > 0:
print(total / count)
the first input does not work, covered by the second input;
when input is "stop", int("stop") is wrong;
When reading the input, do not display a prompt for the user. you should print the ans after the while loop
you can use endless loop and break to solve this problem.
...
while True:
grade = input()
if grade == 'stop':
break
...
print(ans)

How to do the correct casting using a loop in python?

The objective is to write a program that will increase the population every 7 and 35 seconds and decrease every 13 seconds. I am trying to use a loop for this program and I am having some problems with getting the right casting for each variable. Here's the code:
#(1)There is a birth every 7 seconds (2)There is a death every 13 seconds (3)There is a new
immigrant every 35 seconds.
#CURRENT POP: 307,357,870
populationCurrent = input("What is the current population")
x=0
while x!=100:
if (x%7==0):
populationCurrent=populationCurrent+1
x=x+1
elif (x%13==0):
populationCurrent=populationCurrent-1
x=x+1
elif (x%35==0):
populationCurrent+=1
x=x+1
else:
x=x+1
print("The population will be "+int(populationCurrent)+".")
Thank you for your time.
I think you are confused in python2 and python3, there's a difference in input() function of python 2.x and python 3.x, where input() function gives an integer value in python 2 and str in python 3
input() is str by default so, this should be converted to int
populationCurrent = str(input("What is the current population"))
You cannot concatenate string and int
print("The population will be "+str(populationCurrent)+".")
Its easier to do this than iterate through 100 times
populationCurrent += 100//7 + 100//35 - 100//13
You need to convert populationCurrent to an integer immediately after you read the string.
populationCurrent = int(input("What is the current population"))
Note that if you don't enter a string that is a valid integer representation, this will raise a ValueError. You might want to consider how to handle that (catch it and use a default value? catch it and try to read another value? Let the exception propagate?)
With this change, you'll have to convert the integer value back to a string for the output:
print("The population will be "+str(populationCurrent)+".")
or using any of the various string formatting tools available. It's better to have populationCurrent as an integer, since there are more places in your code that assume it to be an integer than assume it to be a string.
The only thing you need to do is convert populationCurrent from string to int:
populationCurrent = int(input("What is the current population?"))
The more concerning stuff is that your code doesn't do what it's supposed to: when x is 35 you will only have one birth, since 35 % 7 is 0, but no immigrant will arrive. Do something like this, removing the elif statements which do not make the code that more efficient anyway:
while x!=100:
if (x%7==0):
populationCurrent=populationCurrent+1
if (x%13==0):
populationCurrent=populationCurrent-1
if (x%35==0):
populationCurrent+=1
x=x+1
print("The population will be ", populationCurrent, ".")
Though still note that the loop will stop after x gets to 100. You could reset it but I don't know for how long you want it to run.
def intInput(prompt):
while 1:
try: return int(input(prompt))
except ValueError: print("Invalid Input!")
def YearToModifier(x):
if x%35 ==0 or x%7 ==0: return 1
if x%13 == 0: return -1
return 0
populationCurrent = intInput("What is the current population?") #ensure you get an int
n_years = intInput("How Many Years?") #ensure you get an int
#in this case populationChange is independent of initial population (this is rarely the case in reality)
populationChange = sum(YearToModifier(x) for x in range(n_years))
#the population in the future is the initialPopulation + population Change ... duh...
populationFuture = populationCurrent + populationChange
print("The Population will be %d!"%populationFuture)
there you go
WRT #martjinpeters comment on OP you could change YearToModifier to
def YearToModifier(x):
return sum([x%35 ==0,x%7 ==0,-1*int(x%13 == 0)])
of coarse as #AshokaLella points out you can calculate the total births/immigrations/deaths for a given number of years without actually visiting each year
births = n_years//7
immigrations = n_years//35
deaths = n_years//13
populationChange = births + immigrations - deaths

Inputting a number and outputting a name?

OK so I have this task at school, I'm a complete beginner but I have most of it down, I need to ask for the number and have it output the corresponding name (it's part "d") I managed to get part C to work but when I try to do the same thing to D it refuses to work. I know I'm probably doing something wrong but as I said I'm a complete beginner.
Also, can I tried changing my c+d to "if" so that I could add another "else" so that if the name/number that was input wasn't in any of the lists that it would return saying "invalid" but I cant seem to be able to change them to if statements.
Anyway here's the code I'm trying to make work, like I said, C works but D refuses to:
flag="F"
choice=""
#Looping-----------------------------------------------------------------------
while choice != "F" and choice !="f":
print( " A. Setup Name, Number and CallsPerDay \n"
" B. Display all names and numbers \n"
" C. Insert name to find out number \n"
" D. Insert number and find out name \n"
" E. Display Min, Max and Average CallsPerDay \n"
" F. Finish the Program")
choice=input("Select an option: \n\n")
#Selection---------------------------------------------------------------------
if choice=="A" or choice =="a":
if flag=="F":
names=["gordon", "david", "graeme", "joyce", "douglas", "brian", "suzanne", "karen"]
numb=[273429, 273666, 273512, 273999, 273123, 273224, 273324, 273424]
CPD=[30, 10, 15, 2, 5, 1, 3, 6]
length=len(numb)
print("Names, Numbers and CallsPerDay have now been set up \n")
flag="T"
elif flag=="T":
print("Lists already set up \n")
#---------------------------------------------------------------------------------
elif choice=="B" or choice=="b":
if flag=="F":
print('Run option A first!')
else:
for i in range(0,length,1):
print(names[i],numb[i], CPD[i], "\n")
#-------------------------------------------------------------------------------
elif choice=="C" or choice=="c":
if flag=="F":
print('Run option A first!')
else:
wanted=input('Name please ').lower()
i=0
while names[i] != wanted:
i=i+1
print('Number',numb[i])
#----------Part that refuses to work------------------------
elif choice=="D" or choice=="d":
if flag=="F":
print('Run option A first!')
else:
wanted=input('Number Please: ')
i=0
while numb[i] != wanted:
i=i+1
print('Number',names[i])
Here is the error I get in the shell when trying to do this:
A. Setup Name, Number and CallsPerDay
B. Display all names and numbers
C. Insert name to find out number
D. Insert number and find out name
E. Display Min, Max and Average CallsPerDay
F. Finish the Program
Select an option:
a
Names, Numbers and CallsPerDay have now been set up
A. Setup Name, Number and CallsPerDay
B. Display all names and numbers
C. Insert name to find out number
D. Insert number and find out name
E. Display Min, Max and Average CallsPerDay
F. Finish the Program
Select an option:
d
Number Please: 223666
Traceback (most recent call last):
File "G:\Lvl 5\sofware\menuNEWex - Copy.py", line 62, in <module>
while numb[i] != wanted:
IndexError: list index out of range
>>>
It should be outputting David, because they are both #2 on their lists
There's a few problems here. First, you need to convert wanted from a string to an integer so your comparison will work:
# Not this, because the return of input is a string
wanted=input('Number Please: ')
# But this. Note this will throw a ValueError if converting to an int fails!
wanted = int(input('Number please: '))
# This one has error handling!
try:
wanted = int(input('Number please: '))
except ValueError:
print("That's not a number")
Also, if your entered number is not in your list numb, your loop will still break when i becomes larger than the last index. Try using the index method instead, as it will either return the index of the number or throw a ValueError. Be careful though - that index is the first index of the element in the list. If the same number is repeated, you'll need another approach that handles conflicts:
try:
i = numb.index(wanted)
print('Number', names[i])
except ValueError:
print("No such number")
You should also consider wrapping your input requests in while loops that look for valid values. For example, you need a number for the above section:
i = None
while i is not None:
try:
i = int(input("Number: "))
except ValueError:
# i is still None
print("Must enter a number!")
An example running would give you this:
Number: a
Must enter a number!
Number: b
Must enter a number!
Number: 33
If you put checking your index in that loop, you get checking for integers and valid values at the same time.

Python if statement with multiple clauses

The code im trying to create is to print a wavelength such as radio waves or microwaves based on the wavelength value input.
userInput = input("Enter wavelength (m) value: ")
waveValue= float(userInput)
if waveValue > 10**-1 :
print("Radio Waves")
elif waveValue < 10**-3 :
print("Microwaves")
elif waveValue < 7*10**-7 :
print("Infared")
elif waveValue <4-10**-7 :
print(" Visible light")
elif waveValue <10**-8 :
print( "Ultraviolet")
elif waveValue <10**-11 :
print( "X-rays")
elif waveValue >10**-11 :
print("Gamma rays")
else :
print()
Any hints on how I can get the second if statement to work. Every input I put in just outputs radio waves because my arguments does not work properly.
Also there is 5 more inputs that I will have to use elif commands for.
Are you trying to use powers of 10 here? Because the convention for "10 to the minus 1" for example, is 1.0e-1. What you have in your code translates to "10 times -1" or -10, which I don't think you intended.
I would rewrite as:
if waveValue > 1.0e-1:
print("Radio Waves")
elif (waveValue > 1.0e-3) and (waveValue < 1.0e-1):
print("Micro Waves")
as a prior answer pointed out, it is also more efficient to order the answers so that one side of the comparison is not needed (those values have already been accounted for by earlier tests).
for example:
if waveValue < 1.0e-3:
<not in current code>
elif waveValue < 1.0e-1:
print("Micro Waves")
else:
print("Radio Waves")
Nothing wrong with your approach for a small number of "break values". For a large number of "break values" you are better off to create a table with the break values and the corresponding action.
i.e., in your case, a table with wavelength and classification. First row containing 10e-1 and "Radio Waves", 2nd row containing 10e-3 and "Microwaves"
In code, you just loop though the until until you find the correct row for waveValue.
This is common in Tax Tables. As a bonus, you can store your tax tables in an external database instead of hard-coding the values in your program.
I think your second statement is wrong.
It says waveValue >10*-1<10*-3 which I think is >-10 and < -30 and if what I say is correct then there can't be numbers bigger than -10 that are smaller than -30
A list of tuples could work quite well here:
wave_categories = []
# Load up your data of definitions
wave_categories.append((1e-3, 'Microwaves'))
wave_categories.append((1e-2, 'Somewaves'))
wave_categories.append((1e-1, 'Radiowaves'))
wave_categories.append((1, 'Ultrawaves'))
Then your detection becomes a loop:
def find_wave(wavelength):
for category_wavelength, name in wave_categories:
if wavelength < category_wavelength:
return name
raise Exception('Wavelength {} not detected in list'.format(wavelength))
To make it work for lots and lots of categories, just add more data to wave_categories.
You can use the bisect module for this:
from bisect import bisect
freqs = [10**-11, 10**-8, 4*10**-7, 7*10**-7, 10**-3, 10**-1]
names = ['Gamma rays', 'X-rays', 'Ultraviolet', 'Visible light',
'Infared', 'Microwaves', 'Radio Waves']
>>> names[bisect(freqs, 10**-2)]
'Radio Waves'
>>> names[bisect(freqs, 10**-4)]
'Microwaves'

Categories

Resources