How can I loop through a concatenation - arrays

I'm trying to split a word with a '.' after every letter which I was successful in doing, however, my next step is to split the current splitted words again but I dont want to repeat variations.
my expected output is this:
input word: amaxa
first loop will give - a.maxa, am.axa, ama.xa, amax.a
then the next split should give - a.m.axa, a.ma.xa,a.max.a,
Essentially I wanted different variations of the word with '.' being added when a full loop had been exhausted however, my main issue was I had '.'s appearing next to each other and I tried to use a continue statement but it didn't work. Below is my source code
print("enter email without #gmail.com")
word = input("word: ")
lenofword = len(word) - 1
for i in range(0,lenofword):
sliceword = word[:1+i] + "." + word[1+i:]
lis.append(sliceword)
print(sliceword)
for j in range(0,lenofword):
slices = sliceword[:1+j] + "." + sliceword[j+1:]
if slices[i:] == slices[:]:
continue
print(slices)
ouput given:
enter email without #gmail.com
word: amax
a.max
am.ax
a.m.ax
am..ax
am..ax
ama.x
a.ma.x
am.a.x
ama..x
basically i want to get rid of the 'am..ax' and 'ama..x'

It is easier to choose the two locations where the dots should be placed (may be the same location for the single dot case). For example:
for i in range(1, lenofword + 1):
for j in range(i, lenofword + 1):
sliced = ".".join(filter(None, [word[:i], word[i:j], word[j:]]))
print(sliced)
This will print the following for the input word "amax":
a.max
a.m.ax
a.ma.x
am.ax
am.a.x
ama.x

Related

Best methods to extract substring into arguments and allow arguments with multiple "main split character" indicated by a character in Lua?

Let's say I have this string
"argument \"some argument\""
which prints out as
argument "some argument"
And now as example, let's say I would want to split it using the "space character" as the "main split character" to split, but allow me to indicate with a character which part to have multiple arguments of. So let's say it would be the quotation mark ". At the it should extract the arguments like so
> [1] = "argument"
> [2] = "some argument"
I am able to do this with the code here:
ExtractArgs = function(text,splitKey)
local skip = 0
local arguments = {}
local curString = ""
for i = 1, text:len() do
if (i <= skip) then continue end
local c = text:sub(i, i)
if (c == "\"") and (text:sub(i-1, i-1) ~= "\\") then
local match = text:sub(i):match("%b\"\"")
if (match) then
curString = ""
skip = i + match:len()
arguments[#arguments + 1] = match:sub(2, -2)
else
curString = curString..c
end
elseif (c == splitKey and curString ~= "") then
arguments[#arguments + 1] = curString
curString = ""
else
if (c == splitKey and curString == "") then
continue
end
curString = curString..c
end
end
if (curString ~= "") then
arguments[#arguments + 1] = curString
end
return arguments
end;
print(ExtractArgs("argument \"some argument\"", " "))
So what's the issue?
I am wondering for better ways. This current way, doesn't allow me to use " as it is being used to process.
Here is another way: Extract substring inbetween quotation marks, but skip \" and turn it into " instead in Lua
but I am wondering if there are even better ways.
Ways that would allow me to have something like this:
argument " argument2" "some argument" "some argument with a quotation mark " inside of it" another_argument"
to turn into something like this
> [1] = 'argument'
> [2] = 'argument2"'
> [3] = 'some argument'
> [4] = 'some argument with a quotation mark " inside of it'
> [5] = 'another_argument"'
The example that I made right now, might sound impossible because of no character really indicating what should be processed and what not.
But I am looking for better ways to extract substrings as arguments while allowing to have arguments as one argument that would normally just get split into arguments.
So if it wouldn't be for the ", \"some arguments\" would have just splitted into "some" and "arguments" instead of "some arguments".
Maybe a method that uses something like Lua does with ' " could be a way.
Because it would be probably impossible to have a perfect working system, that would turn this input """ into " as an extracted argument. I would imagine it just extracting it into this "", an empty string.
However, not if it would look like this '"'. But then the other question would be, how could you allow ''' to extract into '. I would imagine it working if it would be so "'". But this is getting too complicated.
I am wondering, is there even a better way to extract arguments, but allow certain special operation like keeping multiple arguments into one argument, by wrapping it around something, or just in any way?

HNT exchange rates are broken

I would like to obtain the HNT/Helium price via the API. Getting the rates through https://api.coinbase.com/v2/exchange-rates?currency=HNT seems to work like with any other currency, but the rates are completely off.
I noticed that on the website, there actually are two tokens called HNT: Helium and Hento (with Helium definitely being the main one, I had not heard of the other one). However, the rates provided by the API don't correspond to either.
The current results:
API result
0.02013283 = $49.67
HNT - Helium (https://www.coinbase.com/price/helium)
$38.92
HNT - Hinto (https://www.coinbase.com/price/hinto)
$0.0669
That's pretty awesome.
Searching for HINTO on CB comes back with no results but you can get to it directly with the link you provided. Searching for HNT only returns Helium. Yet the API returns the un-searchable results for Hinto when using HNT...
But to answer your question, in case you haven't discovered the solution yet, you can simply change the currency to HELIUM
https://api.coinbase.com/v2/exchange-rates?currency=HELIUM
repsonse:
{"data":{"currency":"HELIUM","rates": [...] {"USD":"30.096511279999998"} [...] }}
From a cell, you could call this function:
"colon separated parameters"
=INDEX( SPLIT( INDEX ( SPLIT( IMPORTDATA("https://api.coinbase.com/v2/exchange-rates?currency=HELIUM", "|", ","), ":"), 0, 48), ","), 0, 1)
"semi colon separated parameters"
=INDEX( SPLIT( INDEX ( SPLIT( IMPORTDATA("https://api.coinbase.com/v2/exchange-rates?currency=HELIUM"; "|"; ","); ":"); 0; 48); ","); 0; 1)
This will get you quoted value: "22.87244131153848"
IMPORTDATA will get the JSon, I use the "|" separator so it comes alltogether
{"data":{"currency":"HELIUM","rates":{"AED":"92.539849932...
SPLIT will separate values on every ":"
col 1. {"data"
col 2. {"currency"
col n. ...
INDEX will get the column where the price of Helium is (the FJD is the next element)
"22.87244131153848","FJD"
SPLIT will separate again the value on the ","
col 1: "22.87244131153848"
col 2: "FJD"
INDEX will finally get the resultant value
"22.87244131153848"

Ruby Array Elements

I am trying to create password Generate in ruby. At the moment all is working just got stuck at the final piece of generating the password.
I asked user if he/she would like the password to include numbers, lowercase or uppercase.
If YES, user will enter 1 and 0 for NO.
I used the code below to generate password if everything is 1. Meaning user want to include numbers, lowercase and uppercase.
if numbers == 1 && lowercase == 1 && uppercase == 1
passGen = [(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10)
end
p passGen
This works 90% of the time. 10% of the time the generated password will not include say any numbers. But everything else present. I am not sure if this is because of the size or length of Array from which the password is sampled.
Anyway lets go to the main problem below
Here is the problem, I am struggling to write the code to generate password if one or more of input is 0. That's if user don't want to include numbers. Or no numbers and uppercase etc . As I can't predict what user may want or not want. I need help on this please.
Thank you.
You will need to make your input array more dynamic:
passGen = []
passGen += (0..9).to_a if numbers == 1
passGen += ('A'..'Z').to_a if uppercase == 1
passGen += ('a'..'z').to_a if lowercase == 1
passGen.sample(10).join
Now, to tackle your other issue with missing characters - this is caused as you are simply taking 10 random characters from an array. So it can just take, for example, all digits.
To tackle this you need to get one character from each generator first and then generate the remaining characters randomly and shuffle the result:
def generators(numbers:, lowercase:, uppercase:)
[
(0..9 if numbers),
('A'..'Z' if uppercase),
('a'..'z' if lowercase)
].compact.map(&:to_a)
end
def generate_password(generators:, length:, min_per_generator: 1)
chars = generators.flat_map {|g| Array.new(min_per_generator) { g.sample }}
chars += Array.new(length - chars.length) { generators.sample.sample }
chars.shuffle.join
end
gens = generators(numbers: numbers == 1, uppercase == 1, lowercase: lowercase == 1)
Array.new(10) { generate_password(generators: gens, length: 10) }
The code doesn't know it needs to include a digit/letter from every group. The sample takes random signs and since you a basically sampling 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz there is a possibility that all the signs will not be digits.
The easiest way to fix it is to check if a sign from every group is in the "password" and then replace a random sign with a sign from group that is not present.
If I were to program this I would do it like that
def random_from_range(range)
range.to_a.sample.to_s
end
def passGen(numbers, lowercase, uppercase)
result = ''
possibleSigns = []
if numbers == 1
range = (0..9)
result += random_from_range(range)
possibleSigns += range.to_a
end
if lowercase == 1
range = ('A'..'Z')
result += random_from_range(range)
possibleSigns += range.to_a
end
if uppercase == 1
range = ('a'..'z')
result += random_from_range(range)
possibleSigns += range.to_a
end
desired_lenth = 10
while result.length < desired_lenth
result += possibleSigns.sample.to_s
end
result
end
puts passGen(1,1,1)
By saying (0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a, you're creating an Array of 10 + 26 + 26 = 62 elements, and then you pick only 10 elements out of it.
At your place I'd wrap password generation around an until block:
def generate_password_with_digits_and_caps
[(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10).join
end
passGen = ''
until passGen.match(/[A-Z]/) && passGen.match(/[a-z]/) && passGen.match(/\d/)
passGen = generate_password_with_digits_and_caps
end
This could also work (closer to your snipppet):
if numbers == 1 && lowercase == 1 && uppercase == 1
passGen = ''
until passGen.match(/[A-Z]/) && passGen.match(/[a-z]/) && passGen.match(/\d/)
passGen = [(0..9).to_a + ('A'..'Z').to_a + ('a'..'z').to_a].flatten.sample(10).join
end
end
Start with something simple and stupid:
passGen = (('0'..'9').to_a.sample(1)+ ('A'..'Z').to_a.sample(1)+('a'..'z').to_a.sample(8).shuffle).join
Technically speaking, this already fulfills your requirement. From the viewpoint of aesthetics and security, the disadvantage here is that the number of upper case characters is always 8. A more elegant solution would be to find three non-zero integers which add up to 10, and can be used as the arguments for the sample call. Also, if no numbers are requested, you simply pass 0 as argument to sample.
Since this exceeds the scope of your question, and I don't even know whether you want to go so far, I don't elaborate on this here further.

How to loop assigning characters in a string to variable?

I need to take a string and assign each character to a new string variable for a Text To Speech engine to read out each character separately, mainly to control the speed at which it's read out by adding pauses in between each character.
The string contains a number which can vary in length from 6 digits to 16 digits, and I've put the below code together for 6 digits but would like something neater to handle any different character count.
I've done a fair bit of research but can't seem to find a solution, plus I'm new to Groovy / programming.
OrigNum= "12 34 56"
Num = OrigNum.replace(' ','')
sNum = Num.split("(?!^)")
sDigit1 = sNum[0]
sDigit2 = sNum[1]
sDigit3 = sNum[2]
sDigit4 = sNum[3]
sDigit5 = sNum[4]
sDigit6 = sNum[5]
Edit: The reason for needing a new variable for each character is the app that I'm using doesn't let the TTS engine run any code. I have to specifically declare a variable beforehand for it to be read out
Sample TTS input: "The number is [var:sDigit1] [pause] [var:sDigit2] [pause]..."
I've tried using [var:sNum[0]] [var:sNum[1]] to read from the map instead but it is not recognised.
Read this about dynamically creating variable names.
You could use a map in your stuation, which is cleaner and more groovy:
Map digits = [:]
OrigNum.replaceAll("\\s","").eachWithIndex { digit, index ->
digits[index] = digit
}
println digits[0] //first element == 1
println digits[-1] //last element == 6
println digits.size() // 6
Not 100% sure what you need, but to convert your input String to output you could use:
String origNum = "12 34 56"
String out = 'The number is ' + origNum.replaceAll( /\s/, '' ).collect{ "[var:$it]" }.join( ' [pause] ' )
gives:
The number is [var:1] [pause] [var:2] [pause] [var:3] [pause] [var:4] [pause] [var:5] [pause] [var:6]

Print words from the corresponding line numbers

Hello Everyone,
I have two files File1 and File2 which has the following data.
File1:
TOPIC:topic_0 30063951.0
2 19195200.0
1 7586580.0
3 2622580.0
TOPIC:topic_1 17201790.0
1 15428200.0
2 917930.0
10 670854.0
and so on..There are 15 topics and each topic have their respective weights. And the first column like 2,1,3 are the numbers which have corresponding words in file2. For example,
File 2 has:
1 i
2 new
3 percent
4 people
5 year
6 two
7 million
8 president
9 last
10 government
and so on.. There are about 10,470 lines of words. So, in short I should have the corresponding words in the first column of file1 instead of the line numbers. My output should be like:
TOPIC:topic_0 30063951.0
new 19195200.0
i 7586580.0
percent 2622580.0
TOPIC:topic_1 17201790.0
i 15428200.0
new 917930.0
government 670854.0
My Code:
import sys
d1 = {}
n = 1
with open("ap_vocab.txt") as in_file2:
for line2 in in_file2:
#print n, line2
d1[n] = line2[:-1]
n = n + 1
with open("ap_top_t15.txt") as in_file:
for line1 in in_file:
columns = line1.split(' ')
firstwords = columns[0]
#print firstwords[:-8]
if firstwords[:-8] == 'TOPIC':
print columns[0], columns[1]
elif firstwords[:-8] != '\n':
num = columns[0]
print d1[n], columns[1]
This code is running when I type print d1[2], columns[1] giving the second word in file2 for all the lines. But when the above code is printed, it is giving an error
KeyError: 10472
there are 10472 lines of words in the file2. Please help me with what I should do to rectify this. Thanks in advance!
In your first for loop, n is incremented with each line until reaching a final value of 10472. You are only setting values for d1[n] up to 10471 however, as you have placed the increment after you set d1 for your given n, with these two lines:
d1[n] = line2[:-1]
n = n + 1
Then on the line
print d1[n], columns[1]
in your second for loop (for in_file), you are attempting to access d1[10472], which evidently doesn't exist. Furthermore, you are defining d1 as an empty Dictionary, and then attempting to access it as if it were a list, such that even if you fix your increment you will not be able to access it like that. You must either use a list with d1 = [], or will have to implement an OrderedDict so that you can access the "last" key as dictionaries are typically unordered in Python.
You can either:
Alter your increment so that you do set a value for d1 in the d1[10472] position, or simply set the value for the last position after your for loop.
Depending on what you are attempting to print out, you could replace your last line with
print d1[-1], columns[1]
to print out the value for the final index position you currently have set.

Resources