can we delete element in list based on certain condition - arrays

I have a Python list:
test_list = ['LeBron James', 'and', 'Nina Mata', 'Dan Brown', 'Derrick Barnes', 'and',
'Gordon C. James', 'J. Kenji López-Alt', 'and', 'Gianna Ruggiero', ]
I want output like this:
final_list = ['LeBron James and Nina Mata', 'Dan Brown', 'Derrick Barnes and
Gordon C. James', 'J. Kenji López-Alt and Gianna Ruggiero']
In short, I want one item before 'and' one item after 'and' to be combined. On the other hand, names coming without 'and' should not be combined and left as it is. How can we do this in Python?

Here's a solution perhaps not too elegant but simple and functional: join all words with a glue symbol that does not happen in any of them (e.g., "~"), replace the resulting "~and~"s with " and "s, and split by the glue symbol again:
"~".join(test_list).replace("~and~", " and ").split("~")
#['LeBron James and Nina Mata', 'Dan Brown',
# 'Derrick Barnes and Gordon C. James',
# 'J. Kenji López-Alt and Gianna Ruggiero']
This should work for groups with more than one "and," too.

Related

Creating an array in Ruby

I am trying to create an array in Ruby. When my function is called to print the array, it seems that the array is undefined. I am wondering if my syntax is off.
Can someone please tell me if this is the correct way to create and instantiate an array in one line, or if the problem is somewhere else in my code?
Below is my Ruby code:
class Game
words = Array["hat", "cat", "ate", "run", "eye", "soup", "date",
"bake", "wake", "grape", "apple", "pride", "drive",
"tacos", "linux", "orange", "purple", "volume",
"liquid", "palace", "molasses", "diamond", "sausage",
"america", "england"]
# starts the game state to play
def start_x
# game logic for begin
puts(words)
end
# if users wins
def win
puts("congratulations! you win!")
end
# if user loses
def death
puts("sorry! you die!")
end
end
You either need to constantize words into WORDS or you need to make those values available through a getter method or an instance variable. Here are some examples:
Constantize, making the array available to any caller:
class Game
WORDS = ['hat', 'cat', 'ate', 'run', 'eye', 'soup', 'date',
'bake', 'wake', 'grape', 'apple', 'pride', 'drive',
'tacos', 'linux', 'orange', 'purple', 'volume',
'liquid', 'palace', 'molasses', 'diamond', 'sausage',
'america', 'england']
def start_x
puts(WORDS)
end
end
And then it works:
⇒ Game.new.start_x
hat
cat
ate
run
eye
soup
date
bake
wake
grape
apple
pride
drive
tacos
linux
orange
purple
volume
liquid
palace
molasses
diamond
sausage
america
england
Or with a getter method:
class Game
def words
#words ||= ['hat', 'cat', 'ate', 'run', 'eye', 'soup', 'date',
'bake', 'wake', 'grape', 'apple', 'pride', 'drive',
'tacos', 'linux', 'orange', 'purple', 'volume',
'liquid', 'palace', 'molasses', 'diamond', 'sausage',
'america', 'england']
end
def start_x
puts(words)
end
end
Or with an instance variable:
class Game
def initialize
#words = ['hat', 'cat', 'ate', 'run', 'eye', 'soup', 'date',
'bake', 'wake', 'grape', 'apple', 'pride', 'drive',
'tacos', 'linux', 'orange', 'purple', 'volume',
'liquid', 'palace', 'molasses', 'diamond', 'sausage',
'america', 'england']
end
def start_x
puts(#words)
end
end
Or combine with an attribute reader:
class Game
attr_reader :words
def initialize
#words = ['hat', 'cat', 'ate', 'run', 'eye', 'soup', 'date',
'bake', 'wake', 'grape', 'apple', 'pride', 'drive',
'tacos', 'linux', 'orange', 'purple', 'volume',
'liquid', 'palace', 'molasses', 'diamond', 'sausage',
'america', 'england']
end
def start_x
puts(words)
end
end
All work the same way and will be used in different circumstances.
Your code doesn't work, because words is a local variable declared outside the methods.
You probably want to have an instance variable here. And it's usually a good idea to separate the game code from the data. So instead of hard-coding the words into the Game class, you pass the data upon initialization:
class Game
def initialize(words)
#words = words
end
def start_x
puts #words
end
# ...
end
To call it:
words = %w[
hat cat ate run eye soup date bake wake grape apple pride drive tacos linux
orange purple volume liquid palace molasses diamond sausage america england
]
game = Game.new(words)
game.start_x
From here on, you could easily extract the data into a words.txt file:
hat
cat
ate
...
sausage
america
england
And load the data via:
words = File.readlines('words.txt' chomp: true)
game = Game.new(words)
game.start_x
This allows you to launch your game with different sets of words without having to modify your code.
I guess this would help you.
class Game
attr_reader :words
def initialize
#words = %w[hat cat ate run eye soup date
bake wake grape apple pride drive
tacos linux orange purple volume
liquid palace molasses diamond sausage
america england]
end
# if users wins
def win
puts("congratulations! you win!")
end
# if user loses
def death
puts("sorry! you die!")
end
end
You can access the words like Game.new.words

How to extract data from an array that contains only one occurrence of an element and only one occurrence of a corresponding element in Perl

I'm trying to figure out how to extract records from a file that contains only one occurrence of a trainer and only one occurrence of a jockey.
Essentially, the record would imply that the jockey has only one ride for the day and it is for trainer X who has only one runner for the day.
Here are some "sample data":
ALLAN DENHAM,MUSWELLBROOK,RACE 5,MOPITTS (10),JEFF PENZA,B,5
ALLAN KEHOE,MUSWELLBROOK,RACE 3,FOXY FIVE (5),KOBY JENNINGS,C,3
ALLAN KEHOE,MUSWELLBROOK,RACE 4,BANGALLEY LAD (3),KOBY JENNINGS,BBB,4
ANDREW ROBINSON,MUSWELLBROOK,RACE 6,TROPHIES GALORE (4),DARRYL MCLELLAN,AAA,6
BEN HILL,MUSWELLBROOK,RACE 4,WHALER BILL (10),GRANT BUCKLEY,BB,4
BEN HILL,MUSWELLBROOK,RACE 5,MR BILL (5),GRANT BUCKLEY,BB,4
BJORN BAKER,MUSWELLBROOK,RACE 3,MISS JAY FOX (9),ALYSHA COLLETT,BB,3
BRETT CAVANOUGH,MUSWELLBROOK,RACE 3,OFFICE AFFAIR (10),RACHAEL MURRAY,B,3
BRETT THOMPSON,MUSWELLBROOK,RACE 7,COSTAS (2),RONALD SIMPSON,BB,7
CODY MORGAN,MUSWELLBROOK,RACE 6,BAJAN GOLD (5),JEFF PENZA,BB,6
CODY MORGAN,MUSWELLBROOK,RACE 7,RAPID EAGLE (9),DARRYL MCLELLAN,B,7
In the sample data, the first record that would meet my criteria would be the following:
BJORN BAKER,MUSWELLBROOK,RACE 3,MISS JAY FOX (9),ALYSHA COLLETT,BB,3
Note: BJORN BAKER only appears once and ALYSHA COLLETT only appears once.
In the sample data, trainer ALLAN DENHAM has only one runner for the day but jockey JEFF PENZA has 2 rides, one for trainer ALLAN DENHAM & one for trainer CODY MORGAN so this does not my meet my criteria.
Another record that would meet my criteria would be the following record:
BRETT CAVANOUGH,MUSWELLBROOK,RACE 3,OFFICE AFFAIR (10),RACHAEL MURRAY,B,3
Note: BRETT CAVANOUGH only appears once and RACHAEL MURRAY only appears once.
BRETT THOMPSON,MUSWELLBROOK,RACE 7,COSTAS (2),RONALD SIMPSON,BB,7
Note: BRETT THOMPSON only appears once and RONALD SIMPSON only appears once.
And so on...
I've loaded the "sample data" (top of page) into an array in Perl and have investigated how to use hash, etc. in order to extract the unique records but I cannot figure out how to extract the required records based on the uniqueness of the combination of the two elements (i.e. one trainer + the one corresponding jockey)
use Data::Dumper;
$infile = "TRAINER-JOCKEY-SAMPLE.txt";
open my $infile, "<:encoding(utf8)", $infile or die "$infile: $!";
my #recs = <$infile>;
close $infile;
my %uniques;
for my $rec (#recs)
{
my ($trainer, $racecourse, $racenum, $hnameandnum, $jockey, $TDRating, $rnum) = split(",", $rec);
++$uniques{$trainer}{$jockey};
}
print Dumper(\%uniques);
for my $trainer (sort keys %uniques)
{
my $answer = join ',', sort keys %{ $uniques{$trainer} };
print "$trainer has unique values $answer\n";
}
Note: I need to print the entire record when successful (see below):
BJORN BAKER,MUSWELLBROOK,RACE 3,MISS JAY FOX (9),ALYSHA COLLETT,BB,3
Your help would be greatly appreciated.
Both the trainer and the jockey have to appear just once in the list (unless the input has duplicate lines).
So, let's just count the occurrences of trainers. To be able to match them to jockeys, we'll store jockeys to trainers in a hash of hashes.
Once we build the two structures, just select the jockeys with only one associated trainer and check that the trainer appeared just once, which had to be with the jockey they were associated to.
#!/usr/bin/perl
use warnings;
use strict;
use feature qw{ say };
my (%jockeys, %trainers);
while (<>) {
my ($jockey, $trainer) = (split /,/)[0, 4];
++$trainers{$trainer};
undef $jockeys{$jockey}{$trainer};
}
for my $jockey (keys %jockeys) {
next if 1 < keys %{ $jockeys{$jockey} };
my $trainer = (keys %{ $jockeys{$jockey} })[0];
say "$jockey,$trainer" if 1 == $trainers{$trainer};
}
Update: To print the whole lines, we need to store them somewhere, too. We can slightly modify the program by remembering the whole lines in another hash; we can use either the trainer or the jockey as the key.
#!/usr/bin/perl
use warnings;
use strict;
my (%jockeys, %trainers, %full);
while (<>) {
my ($jockey, $trainer) = (split /,/)[0, 4];
++$trainers{$trainer};
undef $jockeys{$jockey}{$trainer};
$full{$jockey} = $_;
}
for my $jockey (keys %jockeys) {
next if 1 < keys %{ $jockeys{$jockey} };
my $trainer = (keys %{ $jockeys{$jockey} })[0];
print $full{$jockey} if 1 == $trainers{$trainer};
}

loop through implicit array

I've been stuck on this for awhile now. I'm trying to loop through this array so I can perform some calculations but I cannot figure out how to loop through there values. Any suggestions?
I managed to figure out how to get there collection structures but I want to loop through each structure and grab there values as well and thats what I'm stuck on.
Also, I want to refrain from using cfscript if possible as I'm still in the learning stages of learning coldfusion.
Here is my code:
<cfset houseStuff = {
Bedroom = [
'Luxury Duvet Set with Alternative Down Comforter',
'Accent Coverlet & Shams',
'Two Sets of Luxurious Liens',
'Mattress Pad',
'Blanket',
'Six Bed Pillows',
'Clock Radio',
'Twenty Hangers'
],
Bathroom = [
'Four Bath Towels',
'Four Hand Towels',
'Four Face Towels',
'Bath Rug',
'Shower Curtain',
'Stainless Tooth Brush Holder & Soap Dish',
'Wastebasket',
'Artwork',
'Hair Dryer',
'Toilet Brush & Plunger'
],
Dining = [
'Dinnerware',
'Place Mats',
'Napkins',
'Flatware',
'Glassware & Wine Glasses'
],
Kitchen = [
'Microwave',
'Cookware',
'Mixing Bowls',
'Baking Dish',
'Colander',
'Stainless Utensil Holder',
'Large Fork',
'Large Spoon',
'Spatula',
'Whisk',
'Measuring Spoon & Cup',
'Carving & Paring Knives',
'Four Steak Knives',
'Cutting Board',
'Salt & Pepper Set',
'Wine Opener',
'Coffee Maker',
'Toaster',
'Electric Can Opener',
'Flatware Tray',
'Kitchen Wastebasket',
'Dish Towels',
'Pot Holders',
'Pitcher',
'10" Non-Stick Frying Pan',
'Cookie Sheet',
'Stainless Steel Electric Tea Kettle',
'3 Piece Non-Metal (Spatula, Spoon, Paste Spoon) Combo'
],
Micellaneous = [
'Iron & Cutting Board',
'Cordless Dual Phone with Digital Answering Machine',
'Broom',
'Dust Pan',
'Vacuum',
'Decor',
'Laundry Basket'
],
StarterKit = [
'Bath Tissue',
'Soap',
'Shampoo & Conditioner',
'Paper Towels',
'Sponge',
'Laundry Soap',
'Dishwasher Detergent',
'Liquid Dish Soap',
'Extra Light Bulbs',
'Coffee',
'Sugar',
'Creamer',
'Bottled Water',
'Oatmeal',
'Breakfast Bars',
'Peanuts',
'Chips',
'Mints',
'Welcome Information'
],
MasterBedroom = [
'Queen bed',
'Headboard',
'Two Nightstands',
'Dresser & Mirrior',
'Two Lamps',
'Artwork',
'LCD Television'
],
LivingRoom = [
'Sofa',
'Chair',
'End Table',
'Coffee Table',
'Lamp',
'LCD TV w/stand',
'DVD Player',
'Artwork'
],
DiningRoom = [
'Dining Table',
'Dining Chairs',
'Artwork'
],
OfficePackage = [
'Desk',
'Chair',
'Lamp'
],
AdditionalBedrooms = [
'Queen or Two Twin Beds',
'Headboard',
'Nightstand',
'Chest of Drawers',
'Lamp',
'Artwork'
]
} />
<cfloop collection="#houseStuff#" item="key">
<cfdump var="#key#"> <br>
<!--- <p style="color:##fff;">#key#:</p> <br /> --->
</cfloop>
Nevermind, I finally figured it out. I had to loop through the collection first. Once I do that create another loop inside it to loop over it's structured values.
<cfloop collection="houseStuff" item="key">
<!---<cfdump var="#houseStuff[key]"> --->
<cfloop from="1" to="#arrayLen(houseStuff[key])#" index="j">
#j#
</cfloop>
</cfloop>
I know you said you'd prefer tags instead of script, but if you are in the learning stages of ColdFusion, I'd still recommend learning how to properly use cfscript. In addition to making your CF a little bit cleaner, it will also make your life a lot easier, especially for things like looping.
Outputting all elements becomes:
<cfscript>
for ( i in houseStuff ) { // loop over the outer Structure
writeOutput(i & ":<br>") ;
for ( j in houseStuff[i] ) { // loop over each inner Array key
writeOutput(j & "<br>") ;
}
writeOutput("<br>");
}
</cfscript>
https://trycf.com/gist/898988f6969a57aa5dece39c42037cfd/acf?theme=monokai
... which, in this context, does get into the philosophical discussion of whether to write output code in tags or script and goes slightly beyond the scope of this question. But I've always been a proponent of learning best-practices at the same time as the basics. Personally, I do tend to follow the tags-for-output view, but for basic looping, the script version is a bit cleaner to me. I'd learn both.
Also check out: http://www.learncfinaweek.com. There's a section in there on Looping with both methods.

Ruby match string in array

I have a string like that: "Men's Beech River Cable T-Shirt" how can I get category from this string?
str = "Men's Beech River Cable T-Shirt"
str2 = "MEN'S GOOSE EYE MOUNTAIN DOWN VEST"
cat1 = str1.split.last # T-Shirt
cat2 = str2.split.last # VEST
TOPS = %w(jacket vest coat blazer parka sweater shirt polo t-shirt)
Desired result:
category_str1 = "Tops" # Since T-Shirt (shirt) is in TOPS constant.
category_str2 = "Tops" # Since vest is in TOPS const.
I don't know how to describe my problem better, I hope you understand it from example provided.
str = "Men's Beech River Cable T-Shirt"
cat_orig = str.split.last # T-Shirt
TOPS = %w(jacket vest coat blazer parka sweater shirt polo)
RE_TOPS = Regexp.union(TOPS)
category = "Tops" if RE_TOPS =~ cat_orig.downcase
Note there are no comma's in the %w() style array syntax.
str = "Men's Beech River Cable T-Shirt"
cat_orig = str.split.last # T-Shirt
TOPS = %w(jacket vest coat blazer parka sweater shirt polo) # suppressed the comma to get a clean array
category = "Tops" if !cat_orig[/(#{TOPS.join("|")})/i].nil?
The join on the TOPS Array build an alternative regex of the form:
(jacket|vest|coat|blazer|parka|sweater|shirt|polo)
If any of those word is present in cat_orig, the return will be the matched word, if not it will return nil.
Note the leading i in the regex to makes it case insensitive.
The best way to do this is through a hash, not an array. Let's say your caetgories look something like this
categories = { "TOPS" => ["shirt", "coat", "blazer"],
"COOKING" => ["knife", "fork", "pan"] }
We can then loop through each category and find if their values include the word in the string
categories.each do |key, value|
puts key if str.downcase.split(' ').any? { |word| categories[key].include?(word) }
end
Loop through each category, and find if the category has a word that the string has.
Note: This does not yet search for substrings.

Output formatting in Python: replacing several %s with the same variable

I'm trying to maintain/update/rewrite/fix a bit of Python that looks a bit like this:
variable = """My name is %s and it has been %s since I was born.
My parents decided to call me %s because they thought %s was a nice name.
%s is the same as %s.""" % (name, name, name, name, name, name)
There are little snippets that look like this all over the script, and I was wondering whether there's a simpler (more Pythonic?) way to write this code. I've found one instance of this that replaces the same variable about 30 times, and it just feels ugly.
Is the only way around the (in my opinion) ugliness to split it up into lots of little bits?
variable = """My name is %s and it has been %s since I was born.""" % (name, name)
variable += """My parents decided to call me %s because they thought %s was a nice name.""" % (name, name)
variable += """%s is the same as %s.""" % (name, name)
Use a dictionary instead.
var = '%(foo)s %(foo)s %(foo)s' % { 'foo': 'look_at_me_three_times' }
Or format with explicit numbering.
var = '{0} {0} {0}'.format('look_at_meeee')
Well, or format with named parameters.
var = '{foo} {foo} {foo}'.format(foo = 'python you so crazy')
Python 3.6 has introduced a simpler way to format strings. You can get details about it in PEP 498
>>> name = "Sam"
>>> age = 30
>>> f"Hello, {name}. You are {age}."
'Hello, Sam. You are 30.'
It also support runtime evaluation
>>>f"{2 * 30}"
'60'
It supports dictionary operation too
>>> comedian = {'name': 'Tom', 'age': 30}
>>> f"The comedian is {comedian['name']}, aged {comedian['age']}."
The comedian is Tom, aged 30.
Use formatting strings:
>>> variable = """My name is {name} and it has been {name} since..."""
>>> n = "alex"
>>>
>>> variable.format(name=n)
'My name is alex and it has been alex since...'
The text within the {} can be a descriptor or an index value.
Another fancy trick is to use a dictionary to define multiple variables in combination with the ** operator.
>>> values = {"name": "alex", "color": "red"}
>>> """My name is {name} and my favorite color is {color}""".format(**values)
'My name is alex and my favorite color is red'
>>>
Use the new string.format:
name = 'Alex'
variable = """My name is {0} and it has been {0} since I was born.
My parents decided to call me {0} because they thought {0} was a nice name.
{0} is the same as {0}.""".format(name)
>>> "%(name)s %(name)s hello!" % dict(name='foo')
'foo foo hello!'
You could use named parameters. See examples here
variable = """My name is {0} and it has been {0} since I was born.
My parents decided to call me {0} because they thought {0} was a nice name.
{0} is the same as {0}.""".format(name)
have a look at Template Strings
If you are using Python 3, than you can also leverage, f-strings
myname = "Test"
sample_string = "Hi my name is {name}".format(name=myname)
to
sample_string = f"Hi my name is {myname}"

Resources