How can I resolve this Loop problem in kotlin? - list

I was watching an old programming tutorial about loops and ranges in Kotlin and I tried to copy that same code but apparently my Kotlin version did not respond well.
The original Source Code was:
val capitals= listOf("London", "Paris", "Rome", "Madrid")
for(capital in capitals){
println(capital)
}
I have 2 Questions: First, why use capital and capitals again?
Also when I introduce the source code kotlin adds these symbols <>.
Updated Kotlin code (The one code causing me concern):
val capitals = listOf<> // (this is normal the problem is <>)
When I add the listOf to the value this automatically shows up.
Also, I don't know why the for(capital in capitals) {...} fails.

The code you provided works as expected:
val capitals = listOf("London", "Paris", "Rome", "Madrid")
for(capital in capitals){
println(capital)
}
Prints:
London
Paris
Rome
Madrid
why use capital and capitals again?
Using capital variable in the for loop you store each value of capitals list by iterating through it to handle it as you want.
When you declare a list like this val capitals = listOf("London", "Paris", "Rome", "Madrid"), it implies that you want to access its elements later. You can access its elements only by its name capitals, which you do in the for loop.
As for generics, classes or interfaces in Kotlin can have type parameters, which defined in <> brackets. List is one of such classes.
If the generic parameters can be inferred, for example you can omit the type arguments and <> brackets.

Related

Pandoc lua filters, turn sections into unnumbered ones

I am developing a pandoc markdown template for a journal whose final format needs sections to be unnumbered, that is, \section and children should become \section*.
I know that is sufficient to add {-} in the markdown next to the header title, but I want to force this behaviour and do not depend on users writing markdown correctly.
I tried with:
function Header(el)
el.classes = 'unnumbered'
return el
end
but it makes the headers disappear... I am totally new to LUA so bear with me.
How should I proceed?
Success!
I needed curly brackets around the class to denote a "table"
function Header(el)
el.classes = {'unnumbered'} -- curly brackets were missing here
return el
end
or use an index since classes is a List:
function Header(el)
el.classes[1] = 'unnumbered' -- classes is a List
return el
end

What's the best way to match strings in a file to case class in Scala?

We have a file that contains data that we want to match to a case class. I know enough to brute force it but looking for an idiomatic way in scala.
Given File:
#record
name:John Doe
age: 34
#record
name: Smith Holy
age: 33
# some comment
#record
# another comment
name: Martin Fowler
age: 99
(field values on two lines are INVALID, e.g. name:John\n Smith should error)
And the case class
case class Record(name:String, age:Int)
I Want to return a Seq type such as Stream:
val records: Stream records
The couple of ideas i'm working with but so far haven't implemented is:
Remove all new lines and treat the whole file as one long string. Then grep match on the string "((?!name).)+((?!age).)+age:([\s\d]+)" and create a new object of my case class for each match but so far my regex foo is low and can't match around comments.
Recursive idea: Iterate through each line to find the first line that matches record, then recursively call the function to match name, then age. Tail recursively return Some(new Record(cumulativeMap.get(name), cumulativeMap.get(age)) or None when hitting the next record after name (i.e. age was never encountered)
?? Better Idea?
Thanks for reading! The file is more complicated than above but all rules are equal. For the curious: i'm trying to parse a custom M3U playlist file format.
I'd use kantan.regex for a fairly trivial regex based solution.
Without fancy shapeless derivation, you can write the following:
import kantan.regex._
import kantan.regex.implicits._
case class Record(name:String, age:Int)
implicit val decoder = MatchDecoder.ordered(Record.apply _)
input.evalRegex[Record](rx"(?:name:\s*([^\n]+))\n(?:age:\s*([0-9]+))").toList
This yields:
List(Success(Record(John Doe,34)), Success(Record(Smith Holy,33)), Success(Record(Martin Fowler,99)))
Note that this solution requires you to hand-write decoder, but it can often be automatically derived. If you don't mind a shapeless dependency, you could simply write:
import kantan.regex._
import kantan.regex.implicits._
import kantan.regex.generic._
case class Record(name:String, age:Int)
input.evalRegex[Record](rx"(?:name:\s*([^\n]+))\n(?:age:\s*([0-9]+))").toList
And get the exact same result.
Disclaimer: I'm the library's author.
You could use Parser Combinators.
If you have the file format specification in BNF or can write one, then Scala can create a parser for you from those rules. This may be more robust than hand-made regex based parsers. It's certainly more "Scala".
I don't have much experience in Scala, but could these regexes work:
You could use (?<=name:).* to match name value, and (?<=age:).* to match the age value. If you use this, remove spaces in found matches, otherwise name: bob will match bob with a space before, you might not want that.
If name: or any other tag is in comment, or comment is after value, something will be matched. Please leave a comment if you want to avoid that.
You could try this:
Path file = Paths.get("file.txt");
val lines = Files.readAllLines(file, Charset.defaultCharset());
val records = lines.filter(s => s.startsWith("age:") || s.startsWith("name:"))
.grouped(2).toList.map {
case List(a, b) => Record(a.replaceAll("name:", "").trim,
b.replaceAll("age:", "").trim.toInt)
}

Applying regexp and finding the highest number in a list

I have got a list of different names. I have a script that prints out the names from the list.
req=urllib2.Request('http://some.api.com/')
req.add_header('AUTHORIZATION', 'Token token=hash')
response = urllib2.urlopen(req).read()
json_content = json.loads(response)
for name in json_content:
print name['name']
Output:
Thomas001
Thomas002
Alice001
Ben001
Thomas120
I need to find the max number that comes with the name Thomas. Is there a simple way to to apply regexp for all the elements that contain "Thomas" and then apply max(list) to them? The only way that I have came up with is to go through each element in the list, match regexp for Thomas, then strip the letters and put the remaining numbers to a new list, but this seems pretty bulky.
You don't need regular expressions, and you don't need sorting. As you said, max() is fine. To be safe in case the list contains names like "Thomasson123", you can use:
names = ((x['name'][:6], x['name'][6:]) for x in json_content)
max(int(b) for a, b in names if a == 'Thomas' and b.isdigit())
The first assignment creates a generator expression, so there will be only one pass over the sequence to find the maximum.
You don't need to go for regex. Just store the results in a list and then apply sorted function on that.
>>> l = ['Thomas001',
'homas002',
'Alice001',
'Ben001',
'Thomas120']
>>> [i for i in sorted(l) if i.startswith('Thomas')][-1]
'Thomas120'

Python loop with condition: using same code whether condition is met or not

I have a dict and a list:
main = {"one": "apple", "two":"pear", "three":"banana", "four":"cherry"}
conditional_list = ["one", "four"]
The conditional list may be empty or contain values (like in the case now). I would like to iterate over the dict "main". BUT: if the conditinal list is not empty, I would like to iterate only over the items that match the conditional list. So:
for key, val in mainlist:
if conditional_list:
if key in conditional_list:
do something
else:
do exactly the same thing
I it possible to set up the iteration in such a way, that I don't have to copy+paste the whole code of "do something" to "else" (the line where it says "do exactly the same thing")? Or to put it in another way: Is there a way to ignore the line "if key in conditional_list" if the condition is NOT met (i.e. the list is empty)?
The thing is, the code "do something" is huge and needs to be updated from time to time, copy+pasting it would make things extremly complicated. Thanks in advance!
What about this:
for key, val in mainlist:
if not conditional_list or key in conditional_list:
do something
My suggestion would be to pass the key to a doSomething() function
Also, you may have a reason, but it looks like the dictionary is being used backwards; given the context, this may be an apt solution for you:
for i in conditional_list:
doSomething(i,d(i),(i in mainlist))

Syntax for list delimiters in template

I'm writing an application that allows the user to configure the output using templates. For example:
Variables:
name = "BoppreH"
language = "Python"
Template:
My name is {name} and I like {language}.
Output:
My name is BoppreH and I like Python.
This works fine for simple data, like strings and numbers, but I can't find a good syntax for lists, more specifically for their delimiters.
fruits = ["banana", "apple", "watermelon"]
I like {???}.
I like banana, apple, watermelon.
In this case the desired delimiter was a comma, but how can the user specify that? Is there some template format with this feature?
I'm more concerned about making the syntax simple to understand, regardless of language or library.
Implement filters, and require their use for non-scalar types.
I like {fruits|join:", "}.
Typically, a list contains an unknown number of members, and sometimes variables/placeholders of its own. An example might be listing the name of a person along with their phone numbers. The desired output might look something like this:
John Doe
555-1212
555-1234
In a templating system that supported this, you'd need two types of variables: One that designated a placeholder for a value (like the curly braces you're using now), and another to denote the start and end of the list. So, something like this:
{name}
{{phone_numbers}}{phone}{{/phone_numbers}}
Your array of values might look like this:
values = [names: "John Doe", phone_numbers: [ phone: "555-1212", phone: "555-1234"]]
Each value in the "phone_numbers" array would create a new instance of everything that existed between {{phone_numbers}} and {{/phone_numbers}}, placing the values contained within those two "tags".