I would like to create an auto-schedule but I have some problems - schedule

Creating a schedule where I introduce a word and the program returns the info I need is what I want. I mean, if I write the word "monday" I would like a response with the subjects I have that day. I did this (very brief example, I have more subjects):
x = int(input("Day of the week: "))
if x == 2:
x = 0
print('9:00-11:00 Biology - Classroom C4B \n11:00-13:00 Maths- Classroom C5')
elif x == 3:
print('11:00-13:00 Physics - Classroom C4B')
This works, but the problem is that I do not want to enter numbers but words. I also tried with eval and works too. However, in that case, I must enter a word between '' because eval reads strings and that is not what I want. How can I improve my program?
Thanks in advance (Python 3)

And because you do not use raw_input( )?
input() actually evaluates the input as Python code.
And in your code x = int(input("Day of the week: ")) only accepts numerics inputs. raw_input() returns the verbatim string entered by the user.
day = raw_input("Day of the week: ")
if day == "monday":
print('9:00-11:00 Biology - Classroom C4B \n11:00-13:00 Maths- Classroom C5')
elif day == "tuesday":
print('11:00-13:00 Physics - Classroom C4B')

Related

How to ask for multiple lines of input and print them out as a list in Python

How do I write a code which prints out multiple lines of input and prints it back as a line? The inputs should look something like this
Enter participant 1: Jack
Enter participant 2: Jill
…
Enter participant 6: Joshua
lanes = int(5)
inputs = []
for x in range(loops):
inputs.append(input("Enter participant ", x))
I went all the way till here to store the values but wasnt sure how to print a different line each time
Python inputs takes in one argument, and you can loop it for as many participants as you want.
inputs = []
for x in range(1, 7) #starts from 1 and loops till 7:
inputs.append(input("Enter participant " + str(x) + ": "))
print(inputs)

Confused Beginner learning Python

I am working on a problem in Python and don't understand the answer.
for number in range(1, 10):
if number % 2 == 0:
print(number)
The answer to this problem is 2,4,6,8
Can anyone explain this answer?
range is a function in python which generates a sequence of integers, for example:
r=range(3)
returns a iterable object range(0,3) which generates sequence of integers from 0 to 3-1(2),inorder for you to see the elements in it , you can loop through it:
for i in r:
print(i)
#prints number from 0 to 3-1
Or, wrap it in a list:
list(range(3)) //returns [0,1,2]
range can take 3 params as input start,end and optionally step.The parameters start and end are basically lower and upper bounds to the sequence.In the above example since we have given only one integer range considers start as 0 and end as 3. This function range(start,end,[step]) generates integers in the following manner: start,start+1....end-1 considering the above example 0,0+1...3-1
if you give both the start and the end params to the range, the function generates integers from start upto but not including end, Example:
for i in range(3,8):print(i) #prints numbers from 3 to 8-1
if you give the third parameter which is the step(which is usually 1 by default), then range adds that number to the sequence :
list(range(3,8)) or list(range(3,8,1)) # will return [3,4,5,6,7],sequence generation will be like:3,3+1,(3+1)+1...
list(range(3,8,2)) #returns [3,5,7];3,3+2,(3+2)+2....
So , coming to your question now :
for number in range(1, 10): if number % 2 == 0: print(number)
In the above code you are basically telling python to loop over the sequence of integeres between 1 to 9 and print the numbers which are divisible by 2,which prints 2,4,6,8.
Hope this helped you :)

Pandas manipulation: matching data from other columns to one column, applied uniquely to all rows

I have a model that predicts 10 words for a particular course in order of likelihood, and I'd like the first 5 words of those words that appear in the course's description.
This is the format of the data:
course_name course_title course_description predicted_word_10 predicted_word_9 predicted_word_8 predicted_word_7 predicted_word_6 predicted_word_5 predicted_word_4 predicted_word_3 predicted_word_2 predicted_word_1
Xmath 32 Precalculus Polynomial and rational functions, exponential... directed scholars approach build african different visual cultures placed global
Xphilos 2 Morality Introduction to ethical and political philosop... make presentation weekly european ways general range questions liberal speakers
My idea is for each row to start iterating from predicted_word_1 until I get the first 5 that are in the description. I'd like to save those words in the order they appear into additional columns description_word_1 ... description_word_5. (If there are <5 predicted words in the description I plan to return NAN in the corresponding columns).
To clarify with an example: if the course_description of a course is 'Polynomial and rational functions, exponential and logarithmic functions, trigonometry and trigonometric functions. Complex numbers, fundamental theorem of algebra, mathematical induction, binomial theorem, series, and sequences. ' and its first few predicted words are irrelevantword1, induction, exponential, logarithmic, irrelevantword2, polynomial, algebra...
I would want to return induction, exponential, logarithmic, polynomial, algebra for that in that order and do the same for the rest of the courses.
My attempt was to define an apply function that will take in a row and iterate from the first predicted word until it finds the first 5 that are in the description, but the part I am unable to figure out is how to create these additional columns that have the correct words for each course. This code will currently only keep the words for one course for all the rows.
def find_top_description_words(row):
print(row['course_title'])
description_words_index=1
for i in range(num_words_per_course):
description = row.loc['course_description']
word_i = row.loc['predicted_word_' + str(i+1)]
if (word_i in description) & (description_words_index <=5) :
print(description_words_index)
row['description_word_' + str(description_words_index)] = word_i
description_words_index += 1
df.apply(find_top_description_words,axis=1)
The end goal of this data manipulation is to keep the top 10 predicted words from the model and the top 5 predicted words in the description so the dataframe would look like:
course_name course_title course_description top_description_word_1 ... top_description_word_5 predicted_word_1 ... predicted_word_10
Any pointers would be appreciated. Thank you!
If I understand correctly:
Create new DataFrame with just 100 predicted words:
pred_words_lists = df.apply(lambda x: list(x[3:].dropna())[::-1], axis = 1)
Please note that, there are lists in each row with predicted words. The order is nice, I mean the first, not empty, predicted word is on the first place, the second on the second place and so on.
Now let's create a new DataFrame:
pred_words_df = pd.DataFrame(pred_words_lists.tolist())
pred_words_df.columns = df.columns[:2:-1]
And The final DataFrame:
final_df = df[['course_name', 'course_title', 'course_description']].join(pred_words_df.iloc[:,0:11])
Hope this works.
EDIT
def common_elements(xx, yy):
temp = pd.Series(range(0, len(xx)), index= xx)
return list(df.reindex(yy).sort_values()[0:10].dropna().index)
pred_words_lists = df.apply(lambda x: common_elements(x[2].replace(',','').split(), list(x[3:].dropna())), axis = 1)
Does it satisfy your requirements?
Adapted solution (OP):
def get_sorted_descriptions_words(course_description, predicted_words, k):
description_words = course_description.replace(',','').split()
predicted_words_list = list(predicted_words)
predicted_words = pd.Series(range(0, len(predicted_words_list)), index=predicted_words_list)
predicted_words = predicted_words[~predicted_words.index.duplicated()]
ordered_description = predicted_words.reindex(description_words).dropna().sort_values()
ordered_description_list = pd.Series(ordered_description.index).unique()[:k]
return ordered_description_list
df.apply(lambda x: get_sorted_descriptions_words(x['course_description'], x.filter(regex=r'predicted_word_.*'), k), axis=1)

How can i add an array of values to Google ortools versus a lower and upper bound?

In the documentation and all examples I can find... in terms of nurse scheduling at least, everyone just declares shift values within the search space of {1,4} lets say for shift 1,2,3,4....
solver = pywrapcp.Solver("schedule_shifts")
num_nurses = 4
num_shifts = 4 # Nurse assigned to shift 0 means not working that day.
num_days = 7
# [START]
# Create shift variables.
shifts = {}
for j in range(num_nurses):
for i in range(num_days):
shifts[(j, i)] = solver.IntVar(0, num_shifts - 1, "shifts(%i,%i)" % (j, i))
shifts_flat = [shifts[(j, i)] for j in range(num_nurses) for i in range(num_days)]
# Create nurse variables.
nurses = {}
for j in range(num_shifts):
for i in range(num_days):
nurses[(j, i)] = solver.IntVar(0, num_nurses - 1, "shift%d day%d" % (j,i))
I want to avoid the use of range of values when I call solver.IntVar(lowerbound, upperbound, ...)
I want IntSolver([available values that you can choose], ...)
I created a matrix of all shifts as the columns flowing from the first day to last. My row indexes don't matter but in each day/shift column, I have the index values of nurses in ranked descending order of who bid the highest for that shift. I want to create then a constraint where if I choose a nurse, I choose the maximum bid that is allowed via other constraints from the column, however I don't know how to do that given the limited documentation ortools has with python IntVar.
Can you try
solver.IntVar([values...], 'name')
It should work.
See https://github.com/google/or-tools/blob/master/examples/python/einav_puzzle2.py

Creating a function to count the number of pos in a pandas instance

I've used NLTK to pos_tag sentences in a pandas dataframe from an old Yelp competition. This returns a list of tuples (word, POS). I'd like to count the number of parts of speech for each instance. How would I, say, create a function to count the number of being verbs in each review? I know how to apply functions to features - no problem there. I just can't wrap my head around how to count things inside tuples inside lists inside a pd feature.
The head is here, as a tsv: https://pastebin.com/FnnBq9rf
Thank you #zhangyulin for your help. After two days, I learned some incredibly important things (as a novice programmer!). Here's the solution!
def NounCounter(x):
nouns = []
for (word, pos) in x:
if pos.startswith("NN"):
nouns.append(word)
return nouns
df["nouns"] = df["pos_tag"].apply(NounCounter)
df["noun_count"] = df["nouns"].str.len()
As an example, for dataframe df, noun count of the column "reviews" can be saved to a new column "noun_count" using this code.
def NounCount(x):
nounCount = sum(1 for word, pos in pos_tag(word_tokenize(x)) if pos.startswith('NN'))
return nounCount
df["noun_count"] = df["reviews"].apply(NounCount)
df.to_csv('./dataset.csv')
There are a number of ways you can do that and one very straight forward way is to map the list (or pandas series) of tuples to indicator of whether the word is a verb, and count the number of 1's you have.
Assume you have something like this (please correct me if it's not, as you didn't provide an example):
a = pd.Series([("run", "verb"), ("apple", "noun"), ("play", "verb")])
You can do something like this to map the Series and sum the count:
a.map(lambda x: 1 if x[1]== "verb" else 0).sum()
This will return you 2.
I grabbed a sentence from the link you shared:
text = nltk.word_tokenize("My wife took me here on my birthday for breakfast and it was excellent.")
tag = nltk.pos_tag(text)
a = pd.Series(tag)
a.map(lambda x: 1 if x[1]== "VBD" else 0).sum()
# this returns 2