I am trying to pass argument from my java GUI to the python algorithm. I have tried many ways but I keep getting unrecognized argument as the error. I am using Process builder to integrate the python code to my java. i need to send fav_movie from java to python.
this is a part of the python code. i am a python beginner so it would be helpful if you could please tell me what is causing this error
def _fuzzy_matching(self, hashmap, fav_movie):
"""
return the closest match via fuzzy ratio.
If no match found, return None
Parameters
----------
hashmap: dict, map movie title name to index of the movie in data
fav_movie: str, name of user input movie
Return
------
index of the closest match
"""
match_tuple = []
# get match
for title, idx in hashmap.items():
ratio = fuzz.ratio(title.lower(), fav_movie.lower())
if ratio >= 60:
match_tuple.append((title, idx, ratio))
# sort
match_tuple = sorted(match_tuple, key=lambda x: x[2])[::-1]
if not match_tuple:
print('Oops! No match is found')
else:
print('Found possible matches in our database: '
'{0}\n'.format([x[0] for x in match_tuple]))
return match_tuple[0][1]
def parse_args():
parser = argparse.ArgumentParser(
prog="Movie Recommender",
description="Run KNN Movie Recommender")
parser.add_argument('--path', nargs='?', default='C:\java programs\qcri 3\ml-latest-small',
help='input data path')
parser.add_argument('--movies_filename', nargs='?', default='movies.csv',
help='provide movies filename')
parser.add_argument('--ratings_filename', nargs='?', default='ratings.csv',
help='provide ratings filename')
parser.add_argument('--movie_name', nargs='?', default='',
help='provide your favourite movie name')
parser.add_argument('--top_n', type=int, default=10,
help='top n movie recommendations')
return parser.parse_args()
if __name__ == '__main__':
# get args
args = parse_args()
data_path = args.path
movies_filename = args.movies_filename
ratings_filename = args.ratings_filename
movie_name = args.movie_name
top_n = args.top_n
# initial recommender system
recommender = KnnRecommender(
os.path.join(data_path, movies_filename),
os.path.join(data_path, ratings_filename))
# set params
recommender.set_filter_params(50, 50)
recommender.set_model_params(20, 'brute', 'cosine', -1)
# make recommendations
recommender.make_recommendations(movie_name, top_n)
this is the error shown:
usage: Movie Recommender [-h] [--path [PATH]]
[--movies_filename [MOVIES_FILENAME]]
[--ratings_filename [RATINGS_FILENAME]]
[--movie_name [MOVIE_NAME]] [--top_n TOP_N]
Movie Recommender: error: unrecognized arguments: toy
this is the java code that accesses the python:
public static void main(String args[]) throws ScriptException, InterruptedException
{
System.out.println("enter movie name");
Scanner s= new Scanner(System.in);
String name= s.nextLine();
ProcessBuilder pb= new ProcessBuilder("python","recomold.py",name);
System.out.println("running file");
Process process = null;
try {
process = pb.start();
inheritIO(process.getInputStream(), System.out);
inheritIO(process.getErrorStream(), System.err);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int err= process.waitFor();
System.out.println("any errors?"+(err==0 ? "no" : "yes ")+err);
try {
System.out.println("python output "+ output(process.getInputStream()));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private static void inheritIO(InputStream src, PrintStream dest) {
new Thread(new Runnable() {
public void run() {
Scanner sc = new Scanner(src);
while (sc.hasNextLine()) {
dest.println(sc.nextLine());
}
}
}).start();
}
private static String output(InputStream inputStream) throws IOException {
StringBuilder sb = new StringBuilder();
BufferedReader br = null;
try{
br= new BufferedReader(new InputStreamReader(inputStream));
String line = null;
while((line=br.readLine())!=null)
{
sb.append(line+"\n");
}
}
finally
{
br.close();
}
return sb.toString();
}
}
It looks like your Python script does not accept a non-option argument as proper input. According to the help text for your Python program, any arguments you provide must come in option/value pair form, like this:
--<option_name> <option_value>
But you're just passing "toy" with no option specifier. So maybe what you want is something like this in your Java code:
ProcessBuilder pb= new ProcessBuilder("python","recomold.py","--movie-name",name);
Related
I am a begginer(recently began learning) at programming in Java and I need help.
I have to read from a file, which contains numbers. I would like to make a method for reading from a file. Then I need to analyze this data and write it in another file.
What I strugle with is if I make a method just to read from a file or do I also have to save this read data into a variable. Where should this variable be declared inside a method (if is inside, how do I use it outside), if is outside how do I use it inside a method and also outside. Can anyone help me clarify this? What am I doing wrong?
My code of what I wrote until now. File from which I had to read has houndreds of numbers.
public class Test1 {
public static void main(String[] args) {
String nameFile = "numbers.txt";
File file = new File(nameFile);
String contentFile ="";
}
//Method for reading a .txt file
private static String readFromFile(String nameFile, String contentFile) {
String line = "";
try {
BufferedReader read = new BufferedReader(new FileReader(nameFile));
while((line = read.readLine()) != null) {
line = contentFIle;
}
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
}
return line;
}
}
Theoretically speaking: mathematical functions get input variables, they preform some transformation on the variables and output the result of the transformation.
For example: f(x) = x - 1, g(x) = x * 2
You can chain functions in a way that one functions output will be the other function input: g(f(2)). In this case, the number 2 is used as an input for function f(x) and the output of f(x) is the input of g(x).
Functions and methods in programming can work in a similar way, but It may be more readable to save function output into meaningful variable names, and then to apply these variables to the next function.
Instead of doing: outputText(processText(readText(someFilename)))
You can write (pseudocode):
someFilename = 'foo'
text = readText(someFilename)
processed = processText(text)
outputText(processed)
In java and in your context this would look like the following:
public class Test1 {
public static void main(String[] args) {
String nameFile = "numbers.txt";
String contentFile = readFromFileByName(nameFile);
String altered = processText(contentFile);
saveToFile(altered, "processed.txt");
}
private static String readFromFileByName(String nameFile) {
String fullRead = "";
try {
File file = new File(nameFile);
BufferedReader read = new BufferedReader(new FileReader(file));
String line; // define line variable
while((line = read.readLine()) != null) {
fullRead += line; // pay attention for the altered code
}
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
} finally {
return fullRead;
}
}
private static List<Integer> stringToIntList(String string) {
return Arrays
.stream(text.split(", "))
.map(Integer::parseInt)
.collect(Collectors.toList());
}
private static String processText(String text) {
String processed = text.replace('H', 'h'); // Some heavy processing :)
return processed;
}
private static void saveToFile(String text, String fileName) {
// save <text> to file with filename <filename>
}
}
1) Line is the variable that you have read to. So you shouldn't change its value.
line = contentFIle;
if you need only first line this method should look like:
private static String readFromFile(String nameFile) {
String line = "";
try {
BufferedReader read = new BufferedReader(new FileReader(nameFile));
line = read.readLine();
read.close();
} catch (IOException e) {
System.out.println("There was an error reading from a file");
}
return line;
}
if you need a list of this:
List<String> lines = Collections.emptyList();
try {
Files.readAllLines(Paths.get(fileName), StandardCharsets.UTF_8);
} catch (IOException e) {
// do something
e.printStackTrace();
}
return lines;
2) Also you don't call readFromFile function. So you need to change the main method:
public static void main(String[] args) {
String nameFile = "numbers.txt";
String contentFile = readFromFile(nameFile);
}
3)For your particular case, there's no sense to call readFromFile with String contentFile because you don't use this variable.
I'm new to Java and I have to read from a file, and then convert what I have read into variables. My file consists of a fruit, then a price and it has a long list of this. The file looks like this:
Bananas,4
Apples,5
Strawberry,8
...
Kiwi,3
So far I have created two variables(double price and String name), then set up a scanner that reads from the file.
public void read_file(){
try{
fruits = new Scanner(new File("fruits.txt"));
print_file();
}
catch(Exception e){
System.out.printf("Could not find file\n");
}
}
public void print_file(){
while(fruits.hasNextLine()){
String a = fruits.nextLine();
System.out.printf("%s\n", a);
return;
}
}
Currently I am only able to print out the entire line. But I was wondering how I could break this up to be able to store the lines into variables.
So your string a has an entire line like Apples,5. So try to split it by comma and store it into variables.
String arr[] = a.split(",");
String name = arr[0];
int number = Integer.parseInt(arr[1]);
Or if prices are not integers, then,
double number = Double.parseDouble(arr[1]);
Using java 8 stream and improved file reading capabilities you can do it as follows. it stores item and count as key value pair in a map. It is easy to access by key afterwards.
I know this Maybe too advance but eventually this will help you later when getting to know new stuff in java.
try (Stream<String> stream = Files.lines(Paths.get("src/test/resources/items.txt"))) {
Map<String, Integer> itemMap = stream.map(s -> s.split(","))
.collect(toMap(a -> a[0], a -> Integer.valueOf(a[1])));
System.out.println(itemMap);
} catch (IOException e) {
e.printStackTrace();
}
output
{Apples=5, Kiwi=3, Bananas=4, Strawberry=8}
You can specify a delimiter for the scanner by calling the useDelimiter method, like:
public static void main(String[] args) {
String str = "Bananas,4\n" + "Apples,5\n" + "Strawberry,8\n";
try (Scanner sc = new Scanner(str).useDelimiter(",|\n")) {
while (sc.hasNext()) {
String fruit = sc.next();
int price = sc.nextInt();
System.out.printf("%s,%d\n", fruit, price);
}
} catch (Exception e) {
e.printStackTrace(System.out);
}
}
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Test {
public static void main(String[] args) {
BufferedReader reader;
try {
reader = new BufferedReader(new FileReader(
"C://Test/myfile.txt")); //Your file location
String line = reader.readLine(); //reading the line
while(line!=null){
if(line!=null && line.contains(",")){
String[] data = line.split(",");
System.out.println("Fruit:: "+data[0]+" Count:: "+Integer.parseInt(data[1]));
}
//going over to next line
line = reader.readLine();
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Im writing a hotel console program, the problem i have at the moment is to load the saved file back to a String[], when the user presses option to load from file.
The text file includes the guest names saved earlier.
Here is the file data
tom
mo
jo
john
meg
bob
jack
veronica
jessica
angelica
And here is all the code I have
Yes thank you i know arrays are 0 index. for loops are starting from 1 because
i want to have
Room1 instead Room0 as first
THANK YOU PROBLEM SOLVED
public class FileLoad {
public String[] readLines(String filename) throws IOException {
FileReader fileReader = new FileReader(filename);
BufferedReader bufferedReader = new BufferedReader(fileReader);
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
bufferedReader.close();
return lines.toArray(new String[lines.size()]);
}
public class Hotel_array {
if (Menu.equalsIgnoreCase("S")) {
save(hotel);
}
if (Menu.equalsIgnoreCase("L")) {
load(hotel);
}
}
}
private static void save(String hotel[]) {
try {
PrintWriter pr = new PrintWriter("data.txt");
for (int i = 1; i < 11; i++) {
pr.println(hotel[i]);
}
pr.close();
} catch (Exception e) {
e.printStackTrace();
System.out.println("No such file exists.");
}
}
public static void load(String[] args) {
FileLoad rf = new FileLoad();
String file = "data.txt";
try {
String[] hotel = rf.readLines(file);
for (String line : hotel) {
System.out.println(line); // IT PRINTS FILE NOT LOADS TO ARRAY
}
} catch (IOException e) {
System.out.println("Unable to create " + file + ": " + e.getMessage());
}
}
}
You could change your FileLoad class and add another method to write the array to the file, just to keep all the file IO in one class.
public class FileLoad {
public static String[] readHotelArray(String filename) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new FileReader(filename));
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedReader.readLine()) != null) {
lines.add(line);
}
bufferedReader.close();
return lines.toArray(new String[lines.size()]);
}
public static void writeHotelArray(String filename, String[] hotel) throws IOException {
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filename, false));
//Write each string from the array to the file as a new line
for (String s : hotel)
bufferedWriter.write(s + "\n");
bufferedWriter.flush();
bufferedWriter.close();
}
}
Note: Both methods are static so you don't have to instantiate a new object since there will always be only one method call on that object
Now you have to change the way you save and load the array in your Hotel_array class. You could use something like this:
//...
private static void save(String[] hotel) {
try {
FileLoad.writeHotelArray("data.txt", hotel);
} catch (Exception e) {
e.printStackTrace();
System.out.println("No such file exists.");
}
}
public static String[] load() {
String file = "data.txt";
String[] hotelArray = null;
try {
hotelArray = FileLoad.readHotelArray(file);
} catch (IOException e) {
System.out.println("Unable to create " + file + ": " + e.getMessage());
}
return hotelArray;
}
//...
and since parameters in java are always pass-by-value (more about that here) you need to return the String array in your load() method. And therefore you also have to change a tiny bit of code in the main method.
From:
//...
if (Menu.equalsIgnoreCase("L")) {
load(hotel);
}
//...
To:
//...
if (Menu.equalsIgnoreCase("L")) {
hotel = load();
}
//...
Hope that helps a bit (:
tomaszsvd, I will leave this here for your review... I thought it might help your Java learning curve. I encourage you to compare the load() method below with your original code. Also study the example output to see what is different.
fwiw, I like scsere's answer, it is a clean design. You should pursue that and mark it as the answer.
Let's focus on the code for Hotel_array.load( String[] args ).
Once Hotel_array.load() calls rf.readLines() you have 2 arrays in memory.
1st array: Hotel_array's main()'s local variable "hotel".
2nd array: load()'s local variable "hotel", which is a temporary variable.
Inside Hotel_array.load() remember that the args parameter ties back to main()'s "hotel" variable.
So load()'s local variable "hotel" has nothing to do with main()'s "hotel" variable.
Just to make this a little more clear I'm going to tweak your load() method:
Sample Output
$ javac *.java
$ cat data.txt
alpha
beta
gamma
delta
$ java Hotel_array
WELCOME TO THE HOTEL BOOKING
Hotel Booking Options
A: To Add customer to a room
V: To View all rooms
E: To Display empty rooms
D: To Delete customer from a room
F: Find room from customer name
O: View rooms alphabetically by name
S: Save to file
L: Load from file
L
Loaded 4 lines from filedata.txt
args[1]=empty, will assign line=alpha
args[2]=empty, will assign line=beta
args[3]=empty, will assign line=gamma
args[4]=empty, will assign line=delta
Hotel Booking Options
A: To Add customer to a room
V: To View all rooms
E: To Display empty rooms
D: To Delete customer from a room
F: Find room from customer name
O: View rooms alphabetically by name
S: Save to file
L: Load from file
V
room 1 is occupied by alpha
room 2 is occupied by beta
room 3 is occupied by gamma
room 4 is occupied by delta
room 5 is empty
room 6 is empty
room 7 is empty
room 8 is empty
room 9 is empty
room 10 is empty
Hotel Booking Options
A: To Add customer to a room
V: To View all rooms
E: To Display empty rooms
D: To Delete customer from a room
F: Find room from customer name
O: View rooms alphabetically by name
S: Save to file
L: Load from file
^C$
Modified Hotel_array.load() method
public static void load(String[] args) {
FileLoad rf = new FileLoad();
String file = "data.txt";
try {
// ORIGINAL String[] hotel = rf.readLines(file);
String[] tempHotelData = rf.readLines(file); // Note the different var name.
System.out.println("Loaded "+tempHotelData.length+" lines from file"+file);
int i = 1; // Following your convetion of staring from index #1.
for (String line : tempHotelData ) {
// ORIGINAL: System.out.println(line); // IT PRINTS FILE NOT LOADS TO ARRAY
// NEW...
// Let's print out what is oging on...
// So let's assign "line" to the "args" array.
// Remember that "args" ties back to main()'s "hotel" variable.
System.out.println("args["+i+"]="+args[i]+", will assign line="+line);
args[i] = line;
i = i + 1;
}
} catch (IOException e) {
// probably should say "Unable to LOAD" vs "Unable to CREATE"...
System.out.println("Unable to create " + file + ": " + e.getMessage());
}
}
Some additional things for you to think about...
1) Do you want to assign a line from a file if somebody is already in a room?
(e.g. it isn't empty).
2) What happens if "data.txt" has more lines than you have rooms?
suppose I have the following text file, how do I read each block of lines separated by 2 empty lines in Java?
Thanks!
Reference Type: Journal Article
Record Number: 153
Author: Yang, W. and Kang, J.
Year: 2005
Title: Acoustic comfort evaluation in urban open public spaces
Journal: Applied Acoustics
Volume: 66
Issue: 2
Pages: 211-229
Short Title: Acoustic comfort evaluation in urban open public spaces
ISSN: 0003682X
DOI: 10.1016/j.apacoust.2004.07.011
'File' Attachments: internal-pdf://0633242026/Acoustic comfort evaluation in urban open public spaces.pdf
Reference Type: Thesis
Record Number: 3318
Author: Wienold, Jan
Year: 2009
Title: Daylight glare in offices
University: Fraunhofer Institute for Solar Energy Systems ISE
Thesis Type: PhD Dissertation
Short Title: Daylight glare in offices
URL: http://publica.fraunhofer.de/eprints/urn:nbn:de:0011-n-1414579.pdf
'File' Attachments: internal-pdf://2172014641/Daylight glare in offices.pdf
It seems that answering questions in this forum is quite picky ... I think its really not necessary. Nevertheless, here's my try via Processing, a programming environment built on top of Java:
import java.util.*;
String fileName = "";
String line;
BufferedReader br;
void setup(){
fileName = "My_EndNote_Library_2014-07-04.txt";
br = createReader(fileName);
}
void draw(){
try {
line = br.readLine();
println(line);
println();
} catch (IOException e) {
e.printStackTrace();
line = null;
}
if (line == null) {
// Stop reading because of an error or file is empty
noLoop();
}
}
Since data (rows) of each block is not the same you can do something like this. Using \n\n as delimiter for each block and \n for each line
import java.io.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
StringBuffer sb = new StringBuffer();
while (true) {
String line = br.readLine();
if (line == null) break;
sb.append(line).append("\n");
}
String[] blocks = sb.toString().split("\n\n");
for (String block : blocks) {
block = block.trim();
// block - individual block from file
String[] data = block.split("\n");
for (String d : data) {
// d - individual line of block
}
}
}
}
There are two flaws in accepted answer though essence of logic is correct that you don't need any complex regex etc ,
1.Code is not OS neutral since \n is hard coded
2.Second, since a \n is added after each line so there would be three \n chars between two blocks instead of two \n chars ( two from two empty lines and one extra from previous block ) . Splitting on two chars will also work but block-1 on wards would contain an extra new line at the beginning so you might require trim .
Code is assuming that file is on class path & not on disk.
import java.io.BufferedReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ReferenceType {
public static void main(String[] args) {
ReferenceType app = new ReferenceType();
String allLines = null;
String[] blocks = null;
String lineSeparator = System.getProperty("line.separator");
try {
allLines = app.getFileAsString(lineSeparator);
blocks = allLines.split(lineSeparator+lineSeparator+lineSeparator);
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private String getFileAsString(String lineSeparator) throws URISyntaxException, IOException {
Path path = Paths.get(this.getClass().getResource("ReferenceType.txt").toURI());
String textLine = null;
StringBuilder builder = new StringBuilder();
try (BufferedReader br = Files.newBufferedReader(path)) {
while ((textLine = br.readLine()) != null) {
builder.append(textLine);
builder.append(lineSeparator);
}
}
return builder.toString();
}
}
I want to invoke outlook from the command line (for various reasons) and wanted to know how I go about discovering the Path to the Outlook.exe file.
I'm pretty sure it's stored in the registry, but was wondering how to go about reading that from Java.
thanks
I found a Microsoft page that describes the procedure, just not in Java.
So I guess the question becomes how do I access the registry from java.
I found this site that might be able to help you. It's a Java Registry wrapper, seems to have a lot of features but no idea how robust the implementation is.
Using Otis' answer the following code does it nicely.
static String getOutlookPath() {
// Message message = new Message();
final String classID;
final String outlookPath;
{ // Fetch the Outlook Class ID
int[] ret = RegUtil.RegOpenKey(RegUtil.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\Outlook.Application\\CLSID", RegUtil.KEY_QUERY_VALUE);
int handle = ret[RegUtil.NATIVE_HANDLE];
byte[] outlookClassID = RegUtil.RegQueryValueEx(handle, "");
classID = new String(outlookClassID).trim(); // zero terminated bytes
RegUtil.RegCloseKey(handle);
}
{ // Using the class ID from above pull up the path
int[] ret = RegUtil.RegOpenKey(RegUtil.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\CLSID\\" + classID + "\\LocalServer32", RegUtil.KEY_QUERY_VALUE);
int handle = ret[RegUtil.NATIVE_HANDLE];
byte[] pathBytes = RegUtil.RegQueryValueEx(handle, "");
outlookPath = new String(pathBytes).trim(); // zero terminated bytes
RegUtil.RegCloseKey(handle);
}
return outlookPath;
}
Below is a solution modified slightly from a similar problem: https://stackoverflow.com/a/6194710/854664
Notice I'm using .pst instead of .xls
import java.io.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class ShowOutlookInstalled {
public static void main(String argv[]) {
try {
Process p = Runtime.getRuntime()
.exec(new String[] { "cmd.exe", "/c", "assoc", ".pst" });
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String extensionType = input.readLine();
input.close();
// extract type
if (extensionType == null) {
outlookNotFoundMessage("File type PST not associated with Outlook.");
} else {
String fileType[] = extensionType.split("=");
p = Runtime.getRuntime().exec(
new String[] { "cmd.exe", "/c", "ftype", fileType[1] });
input = new BufferedReader(new InputStreamReader(p.getInputStream()));
String fileAssociation = input.readLine();
// extract path
Pattern pattern = Pattern.compile("\".*?\"");
Matcher m = pattern.matcher(fileAssociation);
if (m.find()) {
String outlookPath = m.group(0);
System.out.println("Outlook path: " + outlookPath);
} else {
outlookNotFoundMessage("Error parsing PST file association");
}
}
} catch (Exception err) {
err.printStackTrace();
outlookNotFoundMessage(err.getMessage());
}
}
private static void outlookNotFoundMessage(String errorMessage) {
System.out.println("Could not find Outlook: \n" + errorMessage);
}
}