What am I doing wrong in the below Prolog code - recursion

The Program aims at checking whether a student has taken a specified list of courses or not. But it displays false even if the student has taken that list of courses. What am I doing wrong?
Code:
%Structure Of facts
%student(ID,FirstName,LastName,Advisor,CreditsPassed,GPA,CourseTakenList).
%courses_taken(CourseId,CourseTitle, Credit,Grade, NoOfTimesRepeated).
%Fact
student(20135639,'Sara','Haider','Mr. Hussain Al-Arrayed',98,3.95,
[courses_taken('ITCE418', 'PRODUCTIVITY WITH IS TECHNOLOGY',3,'A', 0),
courses_taken('MATHS101', 'CALCULUS I', 3,'A', 0),
courses_taken('ACC112', 'FINANCIAL ACCOUNTING I', 3, 'A', 0),
courses_taken('ECON140', 'MICROECONOMICS', 3,'A', 0),
courses_taken('ENGL219', 'TECHNICAL REPORT WRITING', 3,'A', 0) ] ).
check_prereq([],Id):- !.
check_prereq([course(P)]|T,Id):-
student(Id,_,_,_,_,_, CoursesTakenList),
member( courses_taken(P,_,_,_,_), CoursesTakenList),
check_prereq(T,Id).
The following query should return true, since the student has taken those courses
?- check_prereq([course('ITCE418'), course('ACC112')],20135639).
false.
Am I doing something wrong?

You need to replace : [course(P)]|T with [course(P)|T]
check_prereq([],_):- !.
check_prereq([course(P)|T],Id):-
student(Id,_,_,_,_,_, CoursesTakenList),
member( courses_taken(P,_,_,_,_), CoursesTakenList),
check_prereq(T,Id).
Also in the first line replaced Id with _ (anonymous variable) in order to get rid of warnings(Singleton variable). Now it is working fine:
?- check_prereq([course('ITCE418'), course('ACC112')],20135639).
true ;
false.
Note that it returns true and asking for more solutions returns false but it succeeds as we expected.

Related

MS Project formula calculation returns inconsistent results

In MS Project Professional I have a custom field that returns the correct value...sometimes, no value at other times, and an #ERROR at still other times with no apparent rhyme or reason.
The goal: I need to capture the [Resource Names] field for use in an external application - easy enough - but when I have a fixed units task with limited resource units I need to exclude the "[##%]" portion of the name. Example: Sam[25%] but I need just, "Sam"
The formula: IIf(IsNumeric(InStr(1,[Resource Names],"[")),LEFT([Resource Names],Len([Resource Names])-5),[Resource Names])
The results are in summary:
Marian == M
Sam == #ERROR
Sam[25%] == Sam
IDNR == #ERROR
Core Dev == Cor
Bindu == Bindu
Bindu[50%] == Bindu
Michele == Mi
Michele[25%] == Michele
Disha == empty
Disha[33%] == Disha
Stuart[50%] == Stuart
Stuart == S
Strangely enough, Summary Tasks show no value which is correct.
The need: can someone help me fix the formula? Or, should I just suck it up and manually delete the offending brackets and numbers?
If you only ever have one resource assigned to a task, this formula will work: IIf(0=InStr(1,[Resource Names],"["),[Resource Names],Left([Resource Names],InStr(1,[Resource Names],"[")-1)).
However, building a formula to handle more than one resource would be extremely tedious with the limited functions available. In that case a macro to update the field would work much better:
Sub GetResourceNames()
Dim t As Task
For Each t In ActiveProject.Tasks
Dim resList As String
resList = vbNullString
Dim a As Assignment
For Each a In t.Assignments
resList = resList & "," & a.Resource.Name
Next a
t.Text2 = Mid$(resList, 2)
Next t
End Sub

Regex in if else statement in R

I have a rather simple question. I am trying to get the if else statement below to work.
It is supposed to assign '1' if the if statement is met, 0 otherwise.
My problem is that I cannot get the regex in the if statement to work ('\w*|\W*). It is supposed to specify the condition that the string either is "Registration Required" or Registration required followed by any character. I cannot specify the exact cases, because following the "Registration required" (in the cases where something follows), it will usually be a date (varying for each observation) and a few words.
Registration_cleaned <- c()
for (i in 1:length(Registration)) {
if (Registration[i] == ' Registration Required\\w*|\\W*') {
Meta_Registration_cleaned <- 1
} else {
Meta_Registration_cleaned <- 0
}
Registration_cleaned <- c(Registration_cleaned, Meta_Registration_cleaned)
}
You may use transform together with ifelse function to set the Meta_Registration_cleaned.
For matching the regular expression grep function can be used with pattern "Registration Required\w*".
Registration <- data.frame(reg = c("Registration Required", "Registration Required ddfdqf","some str", "Regixxstration Required ddfdqf"),stringsAsFactors = F)
transform(Registration,Meta_Registration_cleaned = ifelse(grepl("Registration Required\\w*",Registration[,"reg"]), 1, 0))
Gives result:
reg Meta_Registration_cleaned
1 Registration Required 1
2 Registration Required ddfdqf 1
3 some str 0
4 Regixxstration Required ddfdqf 0
I might have misunderstood the OP completely, because I have understood the question entirely differently than anyone else here.
My comment earlier suggested looking for the regex at the end of the string.
Registration <- data.frame(reg = c("Registration Required", "Registration Required ddfdqf","Registration Required 10/12/2000"),stringsAsFactors = F)
#thanks #user1653941 for drafting the sample vector
Registration$Meta_Registration_cleaned <- grepl('Registration required$', Registration$reg, ignore.case = TRUE)
Registration
1 Registration Required TRUE
2 Registration Required ddfdqf FALSE
3 Registration Required 10/12/2000 FALSE
I understand the OP as such that the condition is: Either the string "Registration required" without following characters, or... anything else. Looking forward to the OPs comment.

What is the "some" meaning in Collect result in Scala

"some" is not a special term which makes the googling seem to just ignore that search.
What I am asking is in my learning below:
b.collect:
Array[(Int, String)] = Array((3,dog), (6,salmon), (3,rat), (8,elephant))
d.collect:
Array[(Int, String)] = Array((3,dog), (3,cat), (6,salmon), (6,rabbit), (4,wolf), (7,penguin))
if I do some join and then collect the result, like b.join(d).collect, I will get the following:
Array[(Int, (String, String))] = Array((6,(salmon,salmon)), (6,(salmon,rabbit)), (3,(dog,dog)), (3,(dog,cat)), (3,(rat,dog)), (3,(rat,cat)))
which seems understandable, however, if I do: b.leftOuterJoin(d).collect, I will get:
Array[(Int, (String, Option[String]))] = Array((6,(salmon,Some(salmon))), (6,(salmon,Some(rabbit))), (3,(dog,Some(dog))), (3,(dog,Some(cat))), (3,(rat,Some(dog))), (3,(rat,Some(cat))), (8,(elephant,None)))
My question is why do I get results seems to be expressed differently, I mean why the second result contains "Some"? what's the difference between with "Some" and without "Some"? Can "Some" be removed? Does "Some" have any impact to any later operations as the content of RDD?
Thank you very much.
When you do the normal join as b.join(d).collect, you get Array[(Int, (String, String))]
This is because of only the same key with RDD b and RDD d so it is always guaranteed to have a value so it returns Array[(Int, (String, String))].
But when you use b.leftOuterJoin(d).collect the return type is Array[(Int, (String, Option[String]))] this is because to handle the null. In leftOuterJoin, there is no guarantee that all the keys of RDD b are available in RDD d, So it is returned as Option[String] which contains two values
Some(String) =>If the key is matched in both RDD
None If the key is present in b and not present in d
You can replace Some by getting the value from it and providing the value in case of None as below.
val z = b.leftOuterJoin(d).map(x => (x._1, (x._2._1, x._2._2.getOrElse("")))).collect
Now you should get Array[(Int, (String, String))] and output as
Array((6,(salmon,salmon)), (6,(salmon,rabbit)), (3,(dog,dog)), (3,(dog,cat)), (3,(rat,dog)), (3,(rat,Some(cat)), (8,(elephant,)))
Where you can replace "" with any other string as you require.
Hope this helps.

How to loop through python dictionary keys using wild cards?

I have created a dictionary and am looping through it to create a final, much smaller dictionary. I have successfully done this, but it is long and cumbersome. It seems to me I should be able to loop through using some sort of wildcard. My problem is that I am using user input, but some keys can be a, a_1, a_2, ...a_5. Not all go up to 5 possible options, and some have as few as one. Please be kind, I am new to programming. I have tried the fnmatch() function to no avail.
check_parm=yae_list.values()
new_dict={}
x=int(len(check_parm))
while x>0:
element=check_parm[x-1]
if element in yae_atom_parms_dic:
new_dict[element]=yae_atom_parms_dic.get(element)
elif not yae_atom_parms_dic.get(element):
element_1=element+'_1'
if element_1 in yae_atom_parms_dic:
new_dict[element_1]=yae_atom_parms_dic.get(element_1)
element_2=element+'_2'
if element_2 in yae_atom_parms_dic:
new_dict[element_2]=yae_atom_parms_dic.get(element_2)
element_3=element+'_3'
if element_3 in yae_atom_parms_dic:
new_dict[element_3]=yae_atom_parms_dic.get(element_3)
element_4=element+'_4'
if element_4 in yae_atom_parms_dic:
new_dict[element_4]=yae_atom_parms_dic.get(element_4)
element_5=element+'_5'
if element_5 in yae_atom_parms_dic:
new_dict[element_5]=yae_atom_parms_dic.get(element_5)
if element_1 or element_2 or element_3 or element_4 or element_5:
print("Which one do you want?")
print new_dict
x=x-1
This is working as I would like, giving the output:
Which one do you want?
{'C_1': (6, 4, 1, 2, 's', -21.4, 1.625, 0, 1, 0), 'C_2': (6, 4, 1, 2, 'p', -11.4,1.625,)}
Can try something like this:
import re
constant_keys = "|".join(map(re.escape, yae_list.values()))
re_expression = re.compile("^(%s)(_[1-5])?$" % constant_keys)
allowed_keys = filter(re_expression.match, yea_atom_parms_dic.keys())
new_dict = {key: yea_atom_parms_dic[key] for key in allowed_keys}
print new_dict
In this one, first you construct regular expression by joining all of the yae_list keys by | character (and escaping them) and then you put such an expression into ^(%s)(_[1-5])? which means that the match would be hit when the key is either equal to any of the keys in | sequence optionally suffixed with underscore and the number between 1 and 5. Next you filter the allowed keys and using them you can create the new dict with the keys from allowed_keys list.
Example:
If you have the keys: "C", "a" and "new", then the regular expression would looks as follow: ^(C|a|new)(_[1-5])?$

Neo4j cypher - Compare two collections to get at least one same element

I want to return all users that I follow who are not members of any groups that I am in. If a followed user is a member of even one group that I am in, it should not be returned.
However, I am getting an error:
None.get
Neo.DatabaseError.Statement.ExecutionFailure
when I try this query:
MATCH (g1:groups)<-[:MEMBER_OF]-(u1:users{userid1:"56"})-[:FOLLOWS]->(u2:users)-[:MEMBER_OF]->(g2:groups)
WITH collect(g1.groupid) AS my_groups,u2,collect(g2.groupid) AS foll_groups
WHERE NOT any(t in foll_groups WHERE t IN extract(x IN my_groups))
RETURN u2
Here is one solution:
MATCH (g1:groups)<-[:MEMBER_OF]-(u1:users { userid1:"56" })-[:FOLLOWS]->(u2:users)-[:MEMBER_OF]->(g2:groups)
WITH u2, collect(g2) AS foll_groups, collect(g1) AS my_groups
WITH u2, reduce(dup = FALSE, g IN foll_groups | (dup OR g IN my_groups)) AS has_dup
WHERE NOT has_dup
RETURN u2;

Resources