headers is an array that is populated from a file. When I print headers, I get:
headers = ["The Year", , , "The Make", "The Model"]
I'm trying to use headers.remove(' ') to get rid of those two cells that are just spaces. It will not run or compile with that syntax, and I cannot find what I am doing wrong. I have tested:
def list1 = ['j', 2, 3, 4]
list1.remove('j')
And it works just fine. I cannot figure out what I'm doing wrong.
Assuming that ["The Year", , , "The Make", "The Model"] is actually the toString representation of the list
groovy:000> ["The Year", , , "The Make", "The Model"]
ERROR org.codehaus.groovy.control.MultipleCompilationErrorsException:
startup failed:
groovysh_parse: 1: unexpected token: , # line 1, column 14.
["The Year", , , "The Make", "The Model"]
^
groovy:000> ['"The Year"', '', '', '"The Make"', '"The Model"']
===> ["The Year", , , "The Make", "The Model"]
I think headers.remove(' ') isn't working because the elements aren't actually spaces, they're empty. I'm not sure why headers.remove('') wouldn't work, except that you'd need to use headers.removeAll('').
A better option would be to use something like headers.findAll { it.trim() != '' }.
Related
I have a Ruby on Rails application to enter results and create a league table for a football competition.
I'm trying to input some results by creating records in the database through heroku and I get error messages.
The application isn't perfectly designed: to enter the results, I have to create the fixtures and enter the score for each team. Then, independently I have to record each goal scorer, creating a record for each goal which is either associated with an existing player or requires me to firstly create a new player and then create the goal.
When I ran the code below heroku, I got this error:
syntax error, unexpected ':', expecting keyword_end
Maybe I'm missing something simple about lopping through an array within a hash?
Thank you for any advice!
coalition = Team.find_by(name: "Coalition")
moscow_rebels = Team.find_by(name: "Moscow Rebels")
red_star = Team.find_by(name: "Red Star")
unsanctionables = Team.find_by(name: "The Unsanctionables")
cavalry = Team.find_by(name: "Cavalry")
galactics = Team.find_by(name: "The Galactics")
happy_sundays = Team.find_by(name: "Happy Sundays")
hardmen = Team.find_by(name: "Hardmen")
international = Team.find_by(name: "International")
evropa = Venue.find_by(name: "Evropa")
s28 = Season.find_by(number: 28)
start_time = DateTime.new(2020,9,6,11,0,0,'+03:00')
scheduled_matches_1 =
[
{team_1: cavalry, team_1_goals: 1, team_1_scorers: ["Minaev"], team_2_goals: 6, team_2_scorers: ["Kovalev", "Kovalev", "Kovalev", "Thomas", "Thomas", "Grivachev"], team_2: coalition, time: start_time, venue: evropa, season: s28},
{team_1: hardmen, team_1_goals: 4, team_1_scorers: ["Jones", "Jones", "Jones", "Fusi"], team_2_goals: 2, team_2_scorers: ["Kazamula", "Ario"], team_2: galactics, time: start_time + 1.hour, venue: evropa, season: s28},
{team_1: international, team_1_goals: 9, team_1_scorers: ["Kimonnen", "Kimonnen", "Kimonnen", "Burya", "Burya", "Zakharyaev", "Zakharyaev", "Lavruk", "Rihter"], team_2_goals: 0, team_2_scorers: [], team_2: happy_sundays, time: start_time+2.hours, venue: evropa, season: s28}
]
scheduled_matches.each do |match|
new_fixture = Fixture.create(time: match[:time], venue: match[:venue], season: match[:season])
tf1 = TeamFixture.create(team: match[:team_1], fixture: new_fixture)
tf2 = TeamFixture.create(team: match[:team_2], fixture: new_fixture)
ts1 = TeamScore.create(team_fixture: tf1, total_goals: match{:team_1_goals})
ts2 = TeamScore.create(team_fixture: tf2, total_goals: match{:team_2_goals})
match[:team_1_scorers].each do |scorer|
if Player.exists?(team: tf1.team, last_name: scorer)
Goal.create(team_score: ts1, player: Player.find_by(last_name: scorer))
else
new_player = Player.create(team: tf1.team, last_name: scorer)
Goal.create(team_score: ts1, player: new_player)
end
end
match[:team_2_scorers].each do |scorer_2|
if Player.exists?(team: tf2.team, last_name: scorer_2)
Goal.create(team_score: ts2, player: Player.find_by(last_name: scorer_2))
else
new_player = Player.create(team: tf2.team, last_name: scorer_2)
Goal.create(team_score: ts2, player: new_player)
end
end
end
It looks like you are using braces when you meant to use brackets to access the hash. Below is one of the issues, but the same issue is in ts2.
ts1 = TeamScore.create(team_fixture: tf1, total_goals: match{:team_1_goals})
should be match[:team_1_goals]
ts1 = TeamScore.create(team_fixture: tf1, total_goals: match[:team_1_goals])
It may be because you have scheduled_matches_1 at the top and scheduled_matches.each do... further down.
But the real issue here is that your variable names match the data content, rather than being used to hold the content. If a new team joins your league, you have to change the code. Next week, you are going to have to change the hard-coded date value. Your scheduled_matches_1 data structure includes the active record objects returned by the first set of Team.findByName() calls. It would be easier to fetch these objects from the database inside your loops, and just hold the team name as a string in the hash.
There is some duplication too. Consider that each fixture has a home team and an away team. Each team has a name, and an array (possibly empty) of the players who scored. We don't need the number of goals; we can just count the number of players in the 'scorers' array. The other attributes, like the location and season belong to the fixture, not the team. So your hash might be better as
{
"fixtures": [
{
"home": {
"name": "Cavalry",
"scorers": [
"Minaev"
]
},
"away": {
"name": "Coalition",
"scorers": [
"Kovalev",
"Kovalev",
"Kovalev",
"Thomas",
"Thomas",
"Grivachev"
]
},
"venue": "Evropa",
"season": "s28"
}
]
}
because then you can create a reusable method to process each team. And maybe create a new method that returns the player (which it either finds or creates) which can be called by the loop that adds the goals.
Also, as it stands, I'm not sure the code can handle 'own goals', either. Perhaps something for a future iteration :)
I am trying to figure out the following:
When I run this in the terminal using Ruby, the string in the array is removed until it is done when I continue typing in a string that is in the saxophone_section array. But I still want to be able to remove the string from the array when I type in "alto saxophone 1" and because "alto 1" is found in the input string.
How can I do this when a string in an array matches, regardless of the size of an input string?
saxophone_section = ["alto 1", "alto 2", "tenor 1", "tenor 2", "bari sax"]
until saxophone_section == []
puts "Think of sax parts in a jazz big band."
print ">>"
sax_part = gets.chomp.downcase
# this is the part that is confusing me. Trying to figure out the method in which
# a string in the above array matches an input, whether "alto 1" or "alto saxophone 1"
# or "Eb alto saxophone 1" is typed in ("alto 1" is found in all).
# How can I make it true in all three (or more) cases?
saxophone_section.any?(sax_part)
# I am thinking that this bottom parts one could be used? or not?
parts = saxophone_section.map {|sax| sax.gsub(/\s+/m, ' ').strip.split(" ")}
#this is the loop to delete the item in the array:
if saxophone_section.include?(sax_part) == true
p saxophone_section.delete_if{ |s| s == sax_part}
puts "Damn, you're lucky"
else
puts "Woops! Try again."
end
end
puts "You got all parts."
Converting strings into array and making an intersection operation should be an option. I know, this is not the best solution, but might save your day.
[17] pry(main)> x = "alto saxophone 1"
=> "alto saxophone 1"
[18] pry(main)> y = "i am not an anglophone"
=> "i am not an anglophone"
[19] pry(main)> z = "alto 1"
=> "alto 1"
[20] pry(main)> x.split & z.split == z.split # & is array intersection
=> true
[21] pry(main)> x.split & y.split == y.split
=> false
You should use regex to match the input. So instead of creating an array of strings, try the array of regular expressions like so;
saxophone_section = [/alto\s(?:.*\s)?1/, /alto\s(?:.*\s)?2/, /tenor\s(?:.*\s)?1/, /tenor\s(?:.*\s)?2/, /bari\s(?:.*\s)?sax/]
Then use match with all the elements in the array against the input to find if there is a match with the input string;
sax_part = gets.chomp.downcase
index = saxophone_section.find_index { |regex| sax_part.match(regex) }
Later you can use this index to remove the element from array if it's not nil;
saxophone_section.delete(index)
Or you can just use Array#delete_if method to delete the element from array directly like so;
saxophone_section.delete_if { |regex| sax_part.match(regex) }
Note: You can use https://www.rubular.com to test your regular expressions.
Here's where I'd start with this sort of task; These are great building blocks for human-interfaces on the web or in applications:
require 'regexp_trie'
saxophone_section = ["alto 1", "alto 2", "tenor 1", "tenor 2", "bari sax"]
RegexpTrie.union saxophone_section # => /(?:alto\ [12]|tenor\ [12]|bari\ sax)/
The output of RegexpTrie.union is a pattern that will match all of the strings in saxophone_section. The pattern is concise and efficient, and best of all, doesn't have to be generated by hand.
Applying that pattern to the string being created will show if you have a hit when there's a match, but only when there's enough of the string to match.
That's where a regular Trie is very useful. When you're trying to find what possible hits you could have, prior to having a full match, a Trie can find all the possibilities:
require 'trie'
trie = Trie.new
saxophone_section = ["alto 1", "alto 2", "tenor 1", "tenor 2", "bari sax"]
saxophone_section.each { |w| trie.add(w) }
trie.children('a') # => ["alto 1", "alto 2"]
trie.children('alto') # => ["alto 1", "alto 2"]
trie.children('alto 2') # => ["alto 2"]
trie.children('bari') # => ["bari sax"]
Blend those together and see what you come up with.
My json looks like this:
[
{
"blocked": 1,
"object": {
"ip": "abc",
"src_ip": "abc",
"lan_initiated": true,
"detection": "abc",
"src_port": ,
"src_mac": "abc",
"dst_mac": "abc",
"dst_ip": "abc",
"dst_port": "abc"
},
"object_type": "url",
"threat": "",
"threat_type": "abc",
"device_id": "abc",
"app_id": "abc",
"user_id": "abc",
"timestamp": 1520268249657,
"date": {
"$date": "Mon Mar 05 2018 16:44:09 GMT+0000 (UTC)"
},
"expire": {
"$date": "Fri May 04 2018 16:44:09 GMT+0000 (UTC)"
},
"_id": "abc"
}
]
I have tried:
CREATE EXTERNAL TABLE `table_name`(
reports array<struct<
user_id: string ,
device_id: string ,
app_id: string ,
blocked: string ,
object: struct<ip:string,src_ip:string,lan_initiated:string,detection:string,src_port:string,src_mac:string,dst_mac:string,dstp_ip:string,dst_port:string> ,
object_type: string ,
threat: string ,
threat_type: string ,
servertime:string,
date_t: struct<dat:string>,
expire: struct<dat:string>,
id: string >>)
ROW FORMAT SERDE
'org.openx.data.jsonserde.JsonSerDe'
WITH SERDEPROPERTIES (
'ignore.malformed.json'='false','mapping.dat'='$date', 'mapping.servertime'='timestamp','mapping.date'='date_t','mapping._id'='id')
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
'abc'
and after that
SELECT * FROM table_name
LATERAL VIEW outer explode(reports) exploded_table as rep;
but i get: Vertex did not succeed due to OWN_TASK_FAILURE - killed/failed due to:null.
I have read that because the JSON starts with '[' it cannot be parsed. Any ideas? The structure of the json must be changed?
I believe you have made mistake in specifying location
In the code, you have mentioned
LOCATION
'abc'
LOCATION is expected to be a folder in which your JSON file should be present. You can have any name for the JSON file.
You also need to make sure that the JSON-Serde jar is there in the classpath. If not, use below command before trying to create the table.
hive> add jar /path/to/<json-serde-jar>;
So, I'm trying to set up check_json.pl in NagiosXI to monitor some statistics. https://github.com/c-kr/check_json
I'm using the code with the modification I submitted in pull request #32, so line numbers reflect that code.
The json query returns something like this:
[
{
"total_bytes": 123456,
"customer_name": "customer1",
"customer_id": "1",
"indices": [
{
"total_bytes": 12345,
"index": "filename1"
},
{
"total_bytes": 45678,
"index": "filename2"
},
],
"total": "765.43gb"
},
{
"total_bytes": 123456,
"customer_name": "customer2",
"customer_id": "2",
"indices": [
{
"total_bytes": 12345,
"index": "filename1"
},
{
"total_bytes": 45678,
"index": "filename2"
},
],
"total": "765.43gb"
}
]
I'm trying to monitor the sized of specific files. so a check should look something like:
/path/to/check_json.pl -u https://path/to/my/json -a "SOMETHING" -p "SOMETHING"
...where I'm trying to figure out the SOMETHINGs so that I can monitor the total_bytes of filename1 in customer2 where I know the customer_id and index but not their position in the respective arrays.
I can monitor customer1's total bytes by using the string "[0]->{'total_bytes'}" but I need to be able to specify which customer and dig deeper into file name (known) and file size (stat to monitor) AND the working query only gives me the status (OK,WARNING, or CRITICAL). Adding -p all I get are errors....
The error with -p no matter how I've been able to phrase it is always:
Not a HASH reference at ./check_json.pl line 235.
Even when I can get a valid OK from the example "[0]->{'total_bytes'}", using that in -p still gives the same error.
Links pointing to documentation on the format to use would be very helpful. Examples in the README for the script or in the -h output are failing me here. Any ideas?
I really have no idea what your question is. I'm sure I'm not alone, hence the downvotes.
Once you have the decoded json, if you have a customer_id to search for, you can do:
my ($customer_info) = grep {$_->{customer_id} eq $customer_id} #$json_response;
Regarding the error on line 235, this looks odd:
foreach my $key ($np->opts->perfvars eq '*' ? map { "{$_}"} sort keys %$json_response : split(',', $np->opts->perfvars)) {
# ....................................... ^^^^^^^^^^^^^
$perf_value = $json_response->{$key};
if perfvars eq "*", you appear to be looking for $json_reponse->{"{total}"} for example. You might want to validate the user's input:
die "no such key in json data: '$key'\n" unless exists $json_response->{$key};
This entire business of stringifying the hash ref lookups just smells bad.
A better question would look like:
I have this JSON data. How do I get the sum of total_bytes for the customer with id 1?
See https://stackoverflow.com/help/mcve
I've been doing this for a couple of days, and I'm having this problem:
Whenever I try to encode a map into query string, I get the error "syntax error before: chat_id"
form = %{
"chat_id" => 237799109,
"text" => "OMG a message"
}
{status, body} = URI.encode_query(form)
#=> (SyntaxError) lib/elixir.ex:20: syntax error before: chat_id
But as far as I know this is the map syntax, isn't it? As seen here, where this example is presented:
iex> hd = %{"foo" => 1, "bar" => 2}
iex> URI.encode_query(hd)
"bar=2&foo=1
What is happening here?
Full error message:
== Compilation error on file lib/elixir.ex ==
** (SyntaxError) lib/elixir.ex:20: syntax error before: chat_id
(elixir) lib/kernel/parallel_compiler.ex:117: anonymous fn/4 in Kernel.Paral
lelCompiler.spawn_compilers/1
I don't know why you would get the error you listed, but URI.encode_query/1 only returns a single binary argument. You are trying to pattern match it against a tuple.
Can you paste more of the code instead of just those 2 lines?
iex(2)> URI.encode_query(form)
"chat_id=237&text=OMG+a+message"