Right now I'm using Java API to create file object from resource:
new File(getClass().getResource('/resource.xml').toURI())
Is there any more idiomatic/shorter way to do that in Groovy using GDK?
Depending on what you want to do with the File, there might be a shorter way. Note that URL has GDK methods getText(), eachLine{}, and so on.
Illustration 1:
def file = new File(getClass().getResource('/resource.xml').toURI())
def list1 = []
file.eachLine { list1 << it }
// Groovier:
def list2 = []
getClass().getResource('/resource.xml').eachLine {
list2 << it
}
assert list1 == list2
Illustration 2:
import groovy.xml.*
def xmlSlurper = new XmlSlurper()
def url = getClass().getResource('/resource.xml')
// OP style
def file = new File(url.toURI())
def root1 = xmlSlurper.parseText(file.text)
// Groovier:
def root2 = xmlSlurper.parseText(url.text)
assert root1.text() == root2.text()
Related
My active choices reactive reference parameter reads the following JSON file
{
"Name": "Tom",
"Age": "25",
"Subjects": ["English", "Physics", "Chemistry", "Biology", "Maths"]
}
The referenced parameters are file, Nos (previous active choices reactive parameter) which is a radio button with values 1, 2, 3, 4, 5
Now based on the values of Nos, I have to display the subjects. This is what I do:
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def config = jsonSlurper.parse(new File(file))
return config.Subjects
With the above code, the output is,
1. English
2. Physics
3. Chemistry
4. Biology
5. Maths
If I try to return config.Subjects.take(Nos) or config.Subjects.subList(Nos), which I expect, if Nos = 3 to be
1. English
2. Physics
3. Chemistry
But I see nothing. Then I tried,
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def config = jsonSlurper.parse(new File(file))
list = []
i = 0
config.Subjects.each {
while (i < Nos){
list.add "$it".toString()
i = i + 1
}
}
return list
But this time, I see 1. English always, no matter which radio button I select. Where am I going wrong?
You code is almost right. You should use take to slice the list. For example take(2) will return the first two elements. So instead of returning config.Subjects, try returning (config.Subjects).take(Nos)
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def config = jsonSlurper.parse(new File(file))
return (config.Subjects).take(Nos)
If Nos is a string, convert it into integer and return like this
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
def config = jsonSlurper.parse(new File(file))
return (config.Subjects).take(Nos.toInteger())
I would like to figure out the most pragmatic way to accept an array (or list) and append to the data structure. Then finally return the new data structure.
Something like this:
def template(array: Array[String]): Array[Nothing] = {
val staging_path = "s3//clone-staging/"
var path_list = Array()
//iterate through each of the items in the array and append to the new string.
for(outputString <- array){
var new_path = staging_path.toString + outputString
println(new_path)
//path_list I thought would add these new staging_path to the array
path_list +: new_path
}
path_list(4)
}
However, calling a single index of the data structure as a shanty way of checking existence, path_list(4) returns an Out of Bounds.
Thanks.
I think you just want to use map here:
val staging_path = "s3//clone-staging/"
val dirs = Array("one", "two", "three", "four", "five")
val paths = dirs.map(dir => staging_path + dir)
println(paths)
// result: paths: Array[String] = Array(s3//clone-staging/one, s3//clone-staging/two, s3//clone-staging/three, s3//clone-staging/four, s3//clone-staging/five)
println(paths.length)
// result: 5
In functional programming land you are generally trying to avoid mutations. Instead, think of it as transforming your input array into a new array.
I have have written this code defining a class
class OrderRecord:
"""Defines an OrderRecord class, suitable for use in keeping track of order records"""
import tools2
def __init__(self, string):
"""Creates a new OrderRecord object"""
string = string.split(',')
self.date = string[0]
self.location = string[1]
self.name = string[2]
self.colour = string[3]
self.order_num = string[4]
self.cost = 0
def cost_of_order(self):
"""Creates a list of the name and adds up the cost of each letter"""
letter = list(self.name)
for let in letter:
self.cost = self.cost + self.tools2.letter_price(let, self.colour)
return self.cost
def __str__(self):
"""Calls the cost_of_order function and returns the split string in the required format"""
self.cost = self.cost_of_order()
return("Date: {0}\nLocation: {1}\nName: {2}\nColour: \
{3}\nOrder Num: {4}\nCost: {5:.2f}".format(self.date, self.location, \
self.name, self.colour, self.order_num, self.cost))
Now I need to write a function that reads a file containing the following:
20130902,Te Rakipaewhenua,Vinas,parauri,8638
20130909,Te Papaioea,McClary,kikorangi,11643
20131215,Kapiti,Labrie,kikorangi,65291
20141106,Waihopai,Labrie,ma,57910
and returns a dictionary that has the location as the key and lists of OrderRecords as the values.
I know this isn't too hard of a task but I have been stuck on this for awhile because I can't get my head around what to do for it.
Any help would be appreciated.
Maybe something like this. It is not the solution but it has what you need with some modifications.
import collections
dct_result = collections.defaultdict(list)
for line in open('file_path'):
fields = line.split(',')
# index 1 being the second column
dct_result[field(1)].append(OrderRecord( some args ))
Below is a fragement of my code
def LoadCategory(self, filter_string):
time.sleep(1)
self.heading = ""
self.Question_title = list()
self.Question_tag = list()
self.Question_body = list()
self.Question_who_ask = list()
self.Question_who_email = list()
self.Question_key = list()
self.Question_Date = list()
# list is then populated
def post(self):
self.response.write(self.Question_body)
# want to print out self.Question_body in post method.
But the list is empty. what is the right way to access the content of the variable ?
Quick solution assuming you are inside a request class. Although using self to assign variables to the class is not a good approach as said before.
def LoadCategory(self, filter_string):
time.sleep(1)
self.heading = ""
self.Question_title = list()
self.Question_tag = list()
self.Question_body = list()
self.Question_who_ask = list()
self.Question_who_email = list()
self.Question_key = list()
self.Question_Date = list()
# list is then populated
def post(self):
self.LoadCategory(filter_string)
self.response.write(self.Question_body)
Also it would be better if you name LoadCategory to load_category or loadcategory. Try following the PEP8 which states that the function names should be lowercase
i am trying to make a UI that display folders from a given directory,
and the user can check or uncheck the folder.
i would like to get the information of what was checked and return the folder
i know i can loop / iterate in a QTableWidget, but if its a view, or its comming from a Qt.Dir how its done?
(even might be a easier way to add the check boxes to the dir view model than making another class)
thanks.
from PyQt4 import QtCore, QtGui
import sys
import argparse
def parseOpt():
parser = argparse.ArgumentParser(description="Check if the files in this folder are valid EXRs")
parser.add_argument("-file", dest="filepath", help="The file path to be checked.")
return parser.parse_args()
ARGS = parseOpt()
class CheckableDirModel(QtGui.QDirModel):
#a class to put checkbox on the folders
def __init__(self, parent=None):
QtGui.QDirModel.__init__(self, None)
self.checks = {}
def data(self, index, role=QtCore.Qt.DisplayRole):
if role != QtCore.Qt.CheckStateRole:
return QtGui.QDirModel.data(self, index, role)
else:
if index.column() == 0:
return self.checkState(index)
def flags(self, index):
return QtGui.QDirModel.flags(self, index) | QtCore.Qt.ItemIsUserCheckable
def checkState(self, index):
if index in self.checks:
return self.checks[index]
else:
return QtCore.Qt.Unchecked
def setData(self, index, value, role):
if (role == QtCore.Qt.CheckStateRole and index.column() == 0):
self.checks[index] = value
self.emit(QtCore.SIGNAL("dataChanged(QModelIndex,QModelIndex)"), index, index)
return True
return QtGui.QDirModel.setData(self, index, value, role)
#def filtering(self, index):
# self.checks.setFilter(QtCore.QDir.Dirs|QtCore.QDir.NoDotAndDotDot)
class Ui_Dialog(QtGui.QDialog):
def __init__(self,parent=None):
QtGui.QDialog.__init__(self,parent)
self.setObjectName("Dialog")
self.resize(600, 500)
self.llayout = QtGui.QVBoxLayout(parent)
self.model = CheckableDirModel()
self.model.setFilter(QtCore.QDir.Dirs|QtCore.QDir.NoDotAndDotDot)
#self.tree = QtGui.QTreeWidget()
self.tree = QtGui.QTreeView()
self.tree.setModel(self.model)
self.tree.setSortingEnabled(True)
self.tree.setRootIndex(self.model.index(ARGS.filepath))
#self.tree.hideColumn(1)
#self.tree.hideColumn(2)
#self.tree.hideColumn(3)
self.tree.setWindowTitle("Dir View")
self.tree.resize(400, 480)
self.tree.setColumnWidth(0,200)
self.but = QtGui.QPushButton(QtCore.QString("Run"))
self.llayout.addWidget(self.tree)
self.llayout.addWidget(self.but)
self.setLayout(self.llayout)
self.but.clicked.connect(self.print_path)
def print_path(self):
print "hello"
root = self.tree.childCount()
print root
for i in range(root):
print i.text()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
ui = Ui_Dialog()
ui.show()
sys.exit(app.exec_())
If I understand you correctly, what you want is to replace your print_path method with the following:
def print_path(self):
print "hello"
for index,value in self.model.checks.items():
if value.toBool():
print self.model.filePath(index)