Prolog assigning "\r" when 13 is used - list

Started learning prolog this past week and am having trouble with how variables are assigned in this particular case where it is a list containing one element inside of a list.
?- X = [[13]].
X = ["\r"]
Why is prolog assigning ["\r"]? What can be done so it assigns that actual value?

It is exactly that "actual value". It just shows up differently on the top level.
In most Prologs, a list of small integers and a list of character codes are identical. In other words, those two, [13] and "\r", cannot be told apart. So, when you put a 13 in a list, your particular Prolog thinks you meant to make a list of (ASCII) codes, and since 13 is the value of the carriage return, this is what it shows you. (Here, a string of characters enclosed in double quotes is just another way of representing that list of small integers). But this really depends on the implementation. Here is what my Prolog (SWI-Prolog v7) tells me:
?- X = [[13]].
X = [[13]].
Just to confuse you even more, you could have written the above in another way: as a list of character codes in 0' notation:
?- X = [0'\r], Y = [0'\xd].
X = Y, Y = [13].
(Not sure what you are going to see: consult the documentation of you implementation for such details.)
The 0' notation is a way to directly take the numerical value of a character: 0'a is the same as 97. So, the X above is the numerical value of the carriage return, which is 13, which is 0xD in hexadecimal.

Related

Universe OCONV argument for zero-padding

I'm looking for some argument (ARG) such that this code:
A = 5
B = OCONV(A,'ARG5')
PRINT B
will print to the screen
00005
Anybody know something which will do this for me?
In Universe I would use the MR% conversion code. Just be aware that it will truncate anything longer than 5 characters.
A = 5
B = OCONV(A,'MR%5')
PRINT B
I use this a lot when I need to use EVAL in a conditional or as an aggregate function in a SQL or other TCL statement like to find the record with the most fields in a file.
SELECT MAX(EVAL "DCOUNT(#RECORD,#FM)") FROM VOC;
SELECT MAX(EVAL "OCONV(DCOUNT(#RECORD,#FM),'MR%8')") FROM VOC;
Masking aside these generally return 2 different values on our system.
I am using UniData, but looking at the commands reference manual I can't see anything quite right, in terms of one simple argument to OCONV, or similar. I came up with these (somewhat kludgy) alternatives, though:
NUMLEN=5
VALUE=5
PRINT CHANGE(SPACES(NUMLEN-LEN(VALUE))," ","0"):VALUE
Here you are using the SPACES function to create that amount of space characters and then convert them to zeros.
PRINT OCONV(VALUE,"MR":NUMLEN:"(#####)")
This is using OCONV but has to define a string with the "mask" to only shew the final 5 digits. So if NUMLEN changes then the mask string definition would have to change.
PRINT OCONV(VALUE,"MR":NUMLEN)[3,NUMLEN]
This version uses OCONV but prints starting at the 3rd character and shews the next NUMLEN characters, therefore trimming off the initial "0." that is made by using the "MR" parameter
PADDED.VALUE = VALUE 'R%5' is the simplest way to do this.

I need help understanding a piece code

I would really appreciate If someone could help me understand it thanks p.s. Im new to code
sentence = "I like my dog I buy my dog toys"
s = sentence.split()
positions = [s.index(x)+1 for x in s]
print(sentence)
print(positions)
I would really appreciate If someone could help me understand it thanks p.s. Im new to code
Jean is correct. Have you done any online python tutorials?
Here goes.
The first line assigns the string "I like my dog I buy my dog toys" to a variable named sentence.
the next line
s = sentence.split()
breaks up the string into an array of substrings and assigns that array to variable s
>>> print(s)
['I', 'like', 'my', 'dog', 'I', 'buy', 'my', 'dog', 'toys']
the next line
positions = [s.index(x)+1 for x in s]
looks for the occurrence of each of each array value and logs its position to the array position
>>> print(positions)
[1, 2, 3, 4, 1, 6, 3, 4, 9]
EDIT
Allow me to elaborate on some key points. First, the split function. Many languages have a split function. They all take a delimiter, the character upon which the string will be split. In Python, the split() function can be called with no delimiter. In this case the function will use a single space character (" "). Thus when we call sentence.split(), it takes the value of the sentence variable and breaks it apart using the single space and returns an array of the various substrings, or pieces. In this case the individual words.
Next, let's look at the line
positions = [s.index(x)+1 for x in s]
Let's consider the following for a moment
for x in s
i = s.index(x)
this is a basic loop that takes each item in array s and places it in variable x. The first pass through this loop takes "I" and assigns it to x. Then we look for the position of "I" in the array of s. Since s contains the words od the sentence in order, the first position, array item 0 contains the value "I". So, the value of variable i becomes 0. The loop continues matching each item in array s and finds the value's corresponding position within the array.
Taking this one step further, we instantiate another array, in this case position. As the loop iterates over the array s finding the corresponding indices of each value, those positions are then placed in the new array position.
Now most people do not necessarily think in terms of zero based lists. Therefore, we take an extra step and add 1 to each position as it is found. So position 0 becomes position 1, and so on.
So what is different about the for loop I used to demonstrate above and the single line of code used in the example of this question? Nothing really. this line
positions = [s.index(x)+1 for x in s]
is simply a condensed form of the for loop. In Python, this is known as List Comprehension.
At this point, this answer is becoming more of a small instructional on Python. I really need to suggest that you seek out and find some tutorials on Python, starting with the one on Pythons documentation site. Another one may be here on TutorialPoint, or Learn Python. There are also great resources on Pluralsite and Cousera as well.
Good luck

Prolog find element in list of lists with preference

I have list of lists like:
L = [[Q,w,E,],[Q,w,Z,r],[A,s,D,f]]
I know the first two and I need to get the rest.
For example I have Q,w and I need to get Z,r or E,r.
I would like to somehow tell that with priority I always want that touple contain Z, but if doesnt exist give me E,r.
I tried:
member([Q,w,Z,VB],[[Q,w,E,o],[Q,w,Z,r],[A,s,D,f]]).
But that always give me Z = E, VB = o
First you need to know the difference in Prolog between an Atom and a Variable, you can read about their syntax here
Now, if you want a list of atoms that begin with an upper-case letter, you must enclose them in single quotes, otherwise prolog will interpret them as variables.
Now if you fix the syntax of your consult, you will get the following result:
?- member(['Q',w,Z,VB],[['Q',w,'E',o],['Q',w,'Z',r],['A',s,'D',f]]).
VB = o,
Z = 'E'
VB = r,
Z = 'Z'
false
Note how in this case I enclosed in single quote all atoms beginning with an upper-case letter, except for Z and VB in the first argument of the member/2 predicate, cause in this case they function as variables to be instanciated by prolog with the atoms needed to complete this case.

'R: Invalid use of repetition operators'

I'm writing a small function in R as follows:
tags.out <- as.character(tags.out)
tags.out.unique <- unique(tags.out)
z <- NROW(tags.out.unique)
for (i in 1:10) {
l <- length(grep(tags.out.unique[i], x = tags.out))
tags.count <- append(x = tags.count, values = l) }
Basically I'm looking to take each element of the unique character vector (tags.out.unique) and count it's occurrence in the vector prior to the unique function.
This above section of code works correctly, however, when I replace for (i in 1:10) with for (i in 1:z) or even some number larger than 10 (18000 for example) I get the following error:
Error in grep(tags.out.unique[i], x = tags.out) :
invalid regular expression 'c++', reason 'Invalid use of repetition operators
I would be extremely grateful if anyone were able to help me understand what's going on here.
Many thanks.
The "+" in "c++" (which you're passing to grep as a pattern string) has a special meaning. However, you want the "+" to be interpreted literally as the character "+", so instead of
grep(pattern="c++", x="this string contains c++")
you should do
grep(pattern="c++", x="this string contains c++", fixed=TRUE)
If you google [regex special characters] or something similar, you'll see that "+", "*" and many others have a special meaning. In your case you want them to be interpreted literally -- see ?grep.
It would appear that one of the elements of tags.out_unique is c++ which is (as the error message plainly states) an invalid regular expression.
You are currently programming inefficiently. The R-inferno is worth a read, noting especially that Growing objects is generally bad form -- it can be extremely inefficient in some cases. If you are going to have a blanket rule, then "not growing objects" is a better one than "avoid loops".
Given you are simply trying to count the number of times each value occurs there is no need for the loop or regex
counts <- table(tags.out)
# the unique values
names(counts)
should give you the results you want.

Pattern match failure on a list in Haskell

I just started working with Haskell and stumbled on a problem.
According to Haskell, I have a pattern match failure, but I fail to see how.
This is the code I try to execute:
statistics :: [Int] -> (Int, Int, Int)
statistics [gradelist] = ( amountParticipants, average, amountInsufficient)
where
amountParticipants= length [gradelist]
average= sum[gradelist] `div` amountParticipants
amountInsufficient= length [number| number<- [gradelist], number<6]
I call 'statistics' with:
statistics[4,6,4,6]
this causes a pattern match failure, while I expect to see : (4, 5, 2)
statistics[6]
gives the answer : ( 1, 6, 0 ) (which is correct).
Can someone tell me why my first call causes this pattern match? Because I'm pretty sure I give a list as an argument
If you write statistics [gradelist] = ... you are pattern matching against a singleton list containing a sole element referred to as gradelist. Hence, your function is only defined for lists of length exactly 1 (such as [6]); it is undefined for the empty list ([]) or lists with two or more elements (such as [4,6,4,6]).
A correct version of your function would read
statistics :: [Int] -> (Int, Int, Int)
statistics gradelist = (amountParticipants, average, amountInsufficient)
where
amountParticipants = length gradelist
average = sum gradelist `div` amountParticipants
amountInsufficient = length [number| number <- gradelist, number < 6]
As #thoferon remarked, you will also need to make special arrangements for the case in which gradelist is empty, in order to avoid dividing by zero when computing average.
Just replace your [gradelist]'s by gradelist as said before. Also, you might want to match against the empty list with [], in order to avoid dividing by zero in average, like :
statistics [] = (0,0,0)
The list syntax [ ] in a pattern deconstructs a list. The pattern [gradelist] matches a list holding exactly one value, and it names the value in the list gradelist. You get a pattern match failure if you try to call the function with a list holding four values.
To match a value without deconstructing it, use a variable as the pattern.