Printing Lists in Haskell new - list

Brand new to haskell and I need to print out the data contained on a seperate row for each individual item
Unsure on how to
type ItemDescr = String
type ItemYear = Int
type ItemPrice = Int
type ItemSold = Int
type ItemSales = Int
type Item = (ItemRegion,ItemDescr,ItemYear,ItemPrice,ItemSold,ItemSales)
type ListItems = [Item]
rownumber x
| x == 1 = ("Scotland","Desktop",2017,900,25,22500)
| x == 2 = ("England","Laptop",2017,1100,75,82500)
| x == 3 = ("Wales","Printer",2017,120,15,1800)
| x == 4 = ("England","Printer",2017,120,60,7200)
| x == 5 = ("England","Desktop",2017,900,50,45000)
| x == 6 = ("Wales","Desktop",2017,900,20,18000)
| x == 7 = ("Scotland","Printer",2017,25,25,3000)
showall
--print??
So for example on each individual line
show
"Scotland","Desktop",2017,900,25,22500
followed by the next record

Tip 1:
Store the data like this
items = [("Scotland","Desktop",2017,900,25,22500),
("England","Laptop",2017,1100,75,82500),
("Wales","Printer",2017,120,15,1800),
("England","Printer",2017,120,60,7200),
("England","Desktop",2017,900,50,45000),
("Wales","Desktop",2017,900,20,18000),
("Scotland","Printer",2017,25,25,3000)]
Tip 2:
Implement this function
toString :: Item -> String
toString = undefined -- do this yourselves
Tip 3:
Try to combine the following functions
unlines, already in the Prelude
toString, you just wrote it
map, does not need any explanation
putStrLn, not even sure if this is a real function, but you need it anyway.
($), you can do without this one, but it will give you bonus points

Related

For loop for a list to prevent vertical display

ini_list = "[('G 02', 'UV', '2.73')]"
res = ini_list.strip('[]')
print(res)
('G 02', 'UV', '2.73')
result = res.strip('()')
print(result)
'G 02', 'UV', '2.73'
I have a list: 'G 02', 'UV', '2.73' and I would like to assign variables to this list
so that the outcome is as follows:
Element = G 02
Reason = UV
Time = 2.73
I have numerous lists that contain those parameters that I would like to later use to plot various things and so would like to extract each parameter from the list and associate it with the specific variable.
I tried to do it by:
Results = res
for index, Parameters in enumerate(Results):
element = Parameters[0]
print(element)
in the hopes that i could extract each item from the list to assign it a variable as mentioned above however when i print element the list prints vertically downwards and it also doesnt let me extract individual indexes.
'
G
0
2
'
,
'
U
V
'
,
'
2
.
7
3
'
how do i get it so it assigns variables to each parameter as mentioned above and so it prints as so:
element = G 02
reason = UV
time = 2.73
if the ini_list is a string such as ini_list = "[('G 02', 'UV', '2.73')]" then you need strip and split methods to do your work such as following,
ini_list = "[('G 02', 'UV', '2.73')]"
res = ini_list.strip('[]')
result = res.strip('()')
result1 = result.split(',')
result1=[x.strip(" ") for x in result1]
result1=[x.strip("''") for x in result1]
element = result1[0]
print("element:",element)
reason =result1[1]
print("reason:",reason)
time=result1[2]
print("time:",time)
output:
element: G 02
reason: UV
time: 2.73

Converting a list to a map in Scala

I want to create a simple program that calculates someone's age after x years. so first you assign someone's current age to a variable, and then I want to use map to display the future ages.
What I have so far is:
val age = 18
val myList = (1 to 2000).toList
Basically, I want the numbers from the list and make it a map key. And for the value, it's a sum of variable and key. so the map would look like this:
1 -> 19, 2 -> 20, 3 -> 21......
How can I accomplish this?
Consider mapping to tuples
val age = 18
val ageBy: Map[Int, Int] = (1 to 2000).map(i => i -> (age + i)).toMap
ageBy(24) // res1: Int = 42

Find starting and ending index of each unique charcters in a string in python

I have a string with characters repeated. My Job is to find starting Index and ending index of each unique characters in that string. Below is my code.
import re
x = "aaabbbbcc"
xs = set(x)
for item in xs:
mo = re.search(item,x)
flag = item
m = mo.start()
n = mo.end()
print(flag,m,n)
Output :
a 0 1
b 3 4
c 7 8
Here the end index of the characters are not correct. I understand why it's happening but how can I pass the character to be matched dynamically to the regex search function. For instance if I hardcode the character in the search function it provides the desired output
x = 'aabbbbccc'
xs = set(x)
mo = re.search("[b]+",x)
flag = item
m = mo.start()
n = mo.end()
print(flag,m,n)
output:
b 2 5
The above function is providing correct result but here I can't pass the characters to be matched dynamically.
It will be really a help if someone can let me know how to achieve this any hint will also do. Thanks in advance
String literal formatting to the rescue:
import re
x = "aaabbbbcc"
xs = set(x)
for item in xs:
# for patterns better use raw strings - and format the letter into it
mo = re.search(fr"{item}+",x) # fr and rf work both :) its a raw formatted literal
flag = item
m = mo.start()
n = mo.end()
print(flag,m,n) # fix upper limit by n-1
Output:
a 0 3 # you do see that the upper limit is off by 1?
b 3 7 # see above for fix
c 7 9
Your pattern does not need the [] around the letter - you are matching just one anyhow.
Without regex1:
x = "aaabbbbcc"
last_ch = x[0]
start_idx = 0
# process the remainder
for idx,ch in enumerate(x[1:],1):
if last_ch == ch:
continue
else:
print(last_ch,start_idx, idx-1)
last_ch = ch
start_idx = idx
print(ch,start_idx,idx)
output:
a 0 2 # not off by 1
b 3 6
c 7 8
1RegEx: And now you have 2 problems...
Looking at the output, I'm guessing that another option would be,
import re
x = "aaabbbbcc"
xs = re.findall(r"((.)\2*)", x)
start = 0
output = ''
for item in xs:
end = start + len(item[0])
output += (f"{item[1]} {start} {end}\n")
start = end
print(output)
Output
a 0 3
b 3 7
c 7 9
I think it'll be in the Order of N, you can likely benchmark it though, if you like.
import re, time
timer_on = time.time()
for i in range(10000000):
x = "aabbbbccc"
xs = re.findall(r"((.)\2*)", x)
start = 0
output = ''
for item in xs:
end = start + len(item[0])
output += (f"{item[1]} {start} {end}\n")
start = end
timer_off = time.time()
timer_total = timer_off - timer_on
print(timer_total)

Compare strings and just keep those who have on same positions different characters [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
my question is the following: I have a file which contains around 70 strings, all of them have 6 characters (either a,c,g or t for every position -> these are short DNA-sequences).
For example:
accggt agctta gggatc gactta ccttgg
What I need are the strings which are completely unique. Which have on every position a different character (base) compared with the other strings.
In this case I would get two matches (I define them as lists but this is only an idea for the output format):
[accggt , gggatc]
[gggatc , ccttgg]
The elements of list one are on every position different and so are also the elements of list 2.
Is there a build-in function which can do it? I also thought of regular expression but I'm not that familar with this approach.
Thanks in advance!
Edit:
Ok, it seems it is not that easy to describe. So lets go into more detail:
Let's take the five strings mentioned above:
I would start to compare the first string with all the other strings and then continue with string 2 comparing with all other strings and so on.
The first character of the first string is an a.
The first character of the second string is also an a.
This means I would discard the second string.
The first character of the third string is an g.
Fine.
The second character of the first string is an c.
The second character of the third string is an g.
Fine.
The third character of the first string is an c.
The third character of the third string is an g.
Fine.
The fourth ... and so on.
And if all characters of a string are different from the characters of another string (on every position like described above) I would keep those two strings and would search for the next strings which are different on every position compared to the strings I already found. Because I only have four letters there should be only four possibilities fo different strings.
I should end up with, probably a list, which contains the groups of strings which are different in every position.
I hope this helps.
You can use the following algorithm: iterate through all possible word combinations in your string and check each pair for equality with if [x == y for (x, y) in zip(word, nextWord)].count(True) == 0:.
Here is a snippet:
s = "accggt agctta gggatc gactta ccttgg"
chks = s.split(" ");
for word in chks:
for nextWord in chks:
if word != nextWord:
if [x == y for (x, y) in zip(word, nextWord)].count(True) == 0:
print([word, nextWord])
Result of the IDEONE demo:
['accggt', 'gggatc']
['gggatc', 'accggt']
['gggatc', 'ccttgg']
['ccttgg', 'gggatc']
UPDATE
You can deduplicate the list with a custom function. Here is an updated snippet:
def dedup(lst):
seen = set()
result = []
for item in lst:
fs = frozenset(item)
if fs not in seen:
result.append(item)
seen.add(fs)
return result
res = []
s = "accggt agctta gggatc gactta ccttgg"
chks = s.split(" ");
for word in chks:
for nextWord in chks:
if word != nextWord:
if [x == y for (x, y) in zip(word, nextWord)].count(True) == 0:
res.append([word, nextWord])
print(dedup(res))
Result: [['accggt', 'gggatc'], ['gggatc', 'ccttgg']].
To check the words by 3, you need to create all possible permutations of the string into 3-word combinations and use something like:
from itertools import permutations
def dedup(lst):
seen = set()
result = []
for item in lst:
fs = frozenset(item)
if fs not in seen:
result.append(item)
seen.add(fs)
return result
res = []
s = "accggt agctta gggatc gactta ccttgg"
chks = s.split(" ");
perms = [p for p in permutations(chks, 3)]
for perm in perms:
if [(x == y or y == z or x == z) for (x, y, z) in zip(*perm)].count(True) == 0:
res.append(perm)
print(dedup(res))
To find the DNA strings which are completely different on every character you have to check every string against any other string if any character of the given string is the same character on the same position in the comparing string.
Here is an example code for that:
# read all dna strings into a list of strings
dna = ['accggt', 'agctta', 'gggatc', 'gactta', 'ccttgg', '123456']
def compare_two_dna(dna1, dna2):
i = 0
l = len(dna1)
while(i < l):
if dna1[i] == dna2[i]:
return True
i += 1
return False
def is_dna_unique(d, dna_strings):
return len(filter(lambda x: compare_two_dna(d, x), dna_strings)) == 1
# filter all items which only occure once in the list
unique_dna = filter(lambda d: is_dna_unique(d, dna), dna)
print(unique_dna)
The result here is: 123456
var dnaList = "accggt agctta gggatc gactta ccttgg".split( " " );
function getUniqueDnas( dna_list ){
var result = [];
for( var d1 in dna_list ){
var isRepeat = false;
var dna1 = dna_list[ d1 ];
for( var d2 in dna_list ){
var dna2 = dna_list[ d2 ];
if( dna1 == dna2 ){
isRepeat = true;
break;
}
}
if( !isRepeat )
result.push( dna1 );
}
return result;
}
var uniqueDnaList = getUniqueDnas( dnaList );

Matlab Codegen build error

I am trying to convert the below Matlab code into C++ using codegen. However it fails at build and I get the error:
"??? Unless 'rows' is specified, the first input must be a vector. If the vector is variable-size, the either the first dimension or the second must have a fixed length of 1. The input [] is not supported. Use a 1-by-0 or 0-by-1 input (e.g., zeros(1,0) or zeros(0,1)) to represent the empty set."
It then points to [id,m,n] = unique(id); being the culprit. Why doesn't it build and what's the best way to fix it?
function [L,num,sz] = label(I,n) %#codegen
% Check input arguments
error(nargchk(1,2,nargin));
if nargin==1, n=8; end
assert(ndims(I)==2,'The input I must be a 2-D array')
sizI = size(I);
id = reshape(1:prod(sizI),sizI);
sz = ones(sizI);
% Indexes of the adjacent pixels
vec = #(x) x(:);
if n==4 % 4-connected neighborhood
idx1 = [vec(id(:,1:end-1)); vec(id(1:end-1,:))];
idx2 = [vec(id(:,2:end)); vec(id(2:end,:))];
elseif n==8 % 8-connected neighborhood
idx1 = [vec(id(:,1:end-1)); vec(id(1:end-1,:))];
idx2 = [vec(id(:,2:end)); vec(id(2:end,:))];
idx1 = [idx1; vec(id(1:end-1,1:end-1)); vec(id(2:end,1:end-1))];
idx2 = [idx2; vec(id(2:end,2:end)); vec(id(1:end-1,2:end))];
else
error('The second input argument must be either 4 or 8.')
end
% Create the groups and merge them (Union/Find Algorithm)
for k = 1:length(idx1)
root1 = idx1(k);
root2 = idx2(k);
while root1~=id(root1)
id(root1) = id(id(root1));
root1 = id(root1);
end
while root2~=id(root2)
id(root2) = id(id(root2));
root2 = id(root2);
end
if root1==root2, continue, end
% (The two pixels belong to the same group)
N1 = sz(root1); % size of the group belonging to root1
N2 = sz(root2); % size of the group belonging to root2
if I(root1)==I(root2) % then merge the two groups
if N1 < N2
id(root1) = root2;
sz(root2) = N1+N2;
else
id(root2) = root1;
sz(root1) = N1+N2;
end
end
end
while 1
id0 = id;
id = id(id);
if isequal(id0,id), break, end
end
sz = sz(id);
% Label matrix
isNaNI = isnan(I);
id(isNaNI) = NaN;
[id,m,n] = unique(id);
I = 1:length(id);
L = reshape(I(n),sizI);
L(isNaNI) = 0;
if nargout>1, num = nnz(~isnan(id)); end
Just an FYI, if you are using MATLAB R2013b or newer, you can replace error(nargchk(1,2,nargin)) with narginchk(1,2).
As the error message says, for codegen unique requires that the input be a vector unless 'rows' is passed.
If you look at the report (click the "Open report" link that is shown) and hover over id you will likely see that its size is neither 1-by-N nor N-by-1. The requirement for unique can be seen if you search for unique here:
http://www.mathworks.com/help/coder/ug/functions-supported-for-code-generation--alphabetical-list.html
You could do one of a few things:
Make id a vector and treat it as a vector for the computation. Instead of the declaration:
id = reshape(1:prod(sizI),sizI);
you could use:
id = 1:numel(I)
Then id would be a row vector.
You could also keep the code as is and do something like:
[idtemp,m,n] = unique(id(:));
id = reshape(idtemp,size(id));
Obviously, this will cause a copy, idtemp, to be made but it may involve fewer changes to your code.
Remove the anonymous function stored in the variable vec and make vec a subfunction:
function y = vec(x)
coder.inline('always');
y = x(:);
Without the 'rows' option, the input to the unique function is always interpreted as a vector, and the output is always a vector, anyway. So, for example, something like id = unique(id) would have the effect of id = id(:) if all the elements of the matrix id were unique. There is no harm in making the input a vector going in. So change the line
[id,m,n] = unique(id);
to
[id,m,n] = unique(id(:));