Python: For loop Concatenation - python

cat = "["
for row in res:
cat = cat + (str((row['weeks'])) + ',')
cat = (cat + "]").replace(',]', ']')
The above bit of code gives a result string as:
[30,31,32,33,34,35,36,37,38,39,40]
However what I want is:
[W30,W31,W32,W33,W34,W35,W36,W37,W38,W39,W40]
I have been unsuccessful in concatenating the W before each number. How could I do this?
This is the unsuccessful code that I tried:
cat = cat + (str('W'+ (row['weeks'])) + ',')

This gives the desired string:
cat = '[{}]'.format(','.join('W{}'.format(i) for i in row['weeks']))
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# this gives 'W30', 'W31', etc.
# ^^^^^^^^^
# this joins them with commas: 'W30,W31,...,W40'
# ^^^^^^^^^^^^^^
# this puts [ ] around

You have done this
cat = cat + (str('W'+ (row['weeks'])) + ',')
It should be
cat = cat + ('W'+ str(row['weeks']) + ',')
if you want it to be a list you could do this
cat = ["W"+str(row['weeks']) for row in res]

code:
cat = '[W' + ',W'.join(str(element) for element in row['weeks']) + ']'

Instead of getting an answer from here (since there are many ways to do it), you should understand what went wrong with your own code.
(str('W'+ (row['weeks'])) + ',')
What is the order of operations here?
We find row['weeks'].
We attempt 'W' + that.
We attempt str on that.
We attempt that + ','.
Presumably, row['weeks'] is an integer, so the addition with 'W' will fail. You must do this after applying str to the integer.

If you want a list made of strings do
cat = [ 'W'+str(row['weeks']) for row in res]
and, if you want a single string, turn the list into a string
string_cat = str(cat)

cat = "[" + ",".join('W' + str(row['weeks']) for row in res) + "]"
For each row in res convert row['weeks'] to string, prefix it with 'W', and join all such strings with the ',' character. Then just add opening [ and closing ].

Related

Format string output

With this python's code I may read all tickers in the tickers.txt file:
fh = open("tickers.txt")
tickers_list = fh.read()
print(tickers_list)
The output that I obtain is this:
A2A.MI, AMP.MI, ATL.MI, AZM.MI, BGN.MI, BMED.MI, BAMI.MI,
Neverthless, I'd like to obtain as ouput a ticker string exactly formatted in this manner:
["A2A.MI", "AMP.MI", "ATL.MI", "AZM.MI", ...]
Any idea?
Thanks in advance.
If you want the output to look in that format you want, you would need to do the following:
tickers_list= "A2A.MI, AMP.MI, ATL.MI, AZM.MI, BGN.MI, BMED.MI, BAMI.MI"
print("["+"".join(['"' + s + '",' for s in tickers_list.split(",")])[:-1]+"]")
With the output:
["A2A.MI"," AMP.MI"," ATL.MI"," AZM.MI"," BGN.MI"," BMED.MI"," BAMI.MI"]
Code explanation:
['"' + s + '",' for s in tickers_list.split(",")]
Creates a list of strings that contain each individual value, with the brackets as well as the comma.
"".join(...)[:-1]
Joins the list of strings into one string, removing the last character which is the extra comma
"["+..+"]"
adds the closing brackets
Another alternative is to simple use:
print(tickers_list.split(","))
However, the output will be slightly different as in:
['A2A.MI', ' AMP.MI', ' ATL.MI', ' AZM.MI', ' BGN.MI', ' BMED.MI', ' BAMI.MI']
Having ' instead of "
A solution for that however is this:
z = str(tickers_list.split(","))
z = z.replace("'",'"')
print(z)
Having the correct output, by replacing that character
you can to use Split function:
tickers_list = fh.read().split(',')

Python print and write output end in ". . ." rather than the complete line

I have tried moving around the strings and variables I am concatenating, using while loops, moved the line and method that I am opening the outfile, etc. No matter what I do my output prints/writes "curl" + my url variable. From there it ends in "..." ex: curl "https://examplesite/...
Does this have something to do with a buffer or slicing problem? Thank you for any and all help. Full code below.
import pandas as pd
# file = open("output.txt","wt")
header_list = ["COLA", "COLB"]
df = pd.read_csv("curl_data.csv", names=header_list)
df_length = len(df)
iterator = 0
with open("output.txt", "w") as file:
for row in df.iterrows():
url = '"https://examplesite'
lic = df.COLA # use %20 instead of spaces
name = df.COLB # use %20 instead of spaces
group = "example group" # use %20 instead of spaces
command = "curl " + url + "license=" + lic + "&name=" + name + "&group=" + group + '"'
print(command)
file.write(str(command))
iterator += 1
if iterator == 1:
break
file.close()
Solved. As Imre Kerr suggested in the comments the problem was with the length of the output.
I changed my for loop to be for i in range(len(df)): this only looped through the dataframe once (as per Barmars suggestion) and changed the references to the columns in my code from df.COLA to df.loc[i, "COLA] so that it did not print the whole dataset everytime. This fixed the problem of the lines being too long and thus I was able to see the full line for each outputted string.

Python: Remove character only from end of string if character is ="/"

I add different Values to the Houdini Variables with Python.
Some of these Variables are file pathes and end with an "/" - others are just names and do not end with an "/".
In my current code I use [:-1] to remove the last character of the filepath, so I dont have the "/".
The problem is, that if I add a Value like "Var_ABC", the result will be "Var_AB" since it also removes the last character.
How can i remove the last character only if the last character is a "/"?
Thats what I have and it works so far:
def set_vars():
count = hou.evalParm('vars_names')
user_name = hou.evalParm('user_name')
for idx in range( 1,count+1):
output = hou.evalParm('vars_' + str(idx))
vars_path_out = hou.evalParm('vars_path_' + str(idx))
vars_path = vars_path_out[:-1]
hou.hscript("setenv -g " + output + "=" + vars_path)
final_vars = hou.hscript("setenv -g " + output + "=" + vars_path)
hou.ui.displayMessage(user_name +", " + "all variables are set.")
Thank you
As #jasonharper mentioned in the comments, you should probably use rstrip here. It is built-in and IMO more readable than the contitional one-liner:
vars_path_out.rstrip('/')
This will strip out those strings which end with / and return without that ending. Otherwise it will return your string as-is.
Try this in your code:
vars_path_out = hou.evalParm('vars_path_' + str(idx))
if vars_path_out[-1] == '/':
vars_path = vars_path_out[:-1]
or
based on the comment of jasonharper
vars_path = vars_path_out.rstrip('/')
This is much better than the first
Use endswith method to check if it ends with /
if vars_path_out.endswith('/')
Or simply check the last character:
if vars_path_out[-1] == '/'
Like this:
vars_path = vars_path_out[:-1] if vars_path_out.endswith('/') else vars_path_out
Or like this:
if vars_path_out.endswith('\'):
vars_path = vars_path_out[:-1]
else:
vars_path = vars_path_out
another way is rstrip method:
vars_path = vars_path_out.rstrip('/')

Separating a string into numbers and letters in python

I started learning python two days ago. Today I built a web scraping script which pulls data from yahoo finance and puts it in a csv file. The problem I have is that some values are string because yahoo finance displays them as such.
For example: Revenue: 806.43M
When I copy them into the csv I cant use them for calculation so I was wondering if it is possible to separate the "806.43" and "M" while still keeping both to see the unit of the number and put them in two different columns.
for the excel writing I use this command:
f.write(revenue + "," + revenue_value + "\n")
where:
print(revenue)
Revenue (ttm)
print(revenue_value)
806.43M
so in the end I should be able to use a command which looks something like this
f.write(revenue + "," + revenue_value + "," + revenue_unit + "\n")
where revenue_value is 806.43 and revenue_unit is M
Hope someone could help with the problem.
I believe the easiest way is to parse the number as string and convert it to a float based on the unit in the end of the string.
The following should do the trick:
def parse_number(number_str) -> float:
mapping = {
"K": 1000,
"M": 1000000,
"B": 1000000000
}
unit = number_str[-1]
number_float = float(number_str[:-1])
return number_float * mapping[unit]
And here's an example:
my_number = "806.43M"
print(parse_number(my_number))
>>> 806430000.0
You can always try regular expressions.
Here's a pretty good online tool to let you practice using Python-specific standards.
import re
sample = "Revenue (ttm): 806.43M"
# Note: the `(?P<name here>)` section is a named group. That way we can identify what we want to capture.
financials_pattern = r'''
(?P<category>.+?):?\s+? # Capture everything up until the colon
(?P<value>[\d\.]+) # Capture only numeric values and decimal points
(?P<unit>[\w]*)? # Capture a trailing unit type (M, MM, etc.)
'''
# Flags:
# re.I -> Ignore character case (upper vs lower)
# re.X -> Allows for 'verbose' pattern construction, as seen above
res = re.search(financials_pattern, sample, flags = re.I | re.X)
Print our dictionary of values:
res.groupdict()
Output:
{'category': 'Revenue (ttm)',
'value': '806.43',
'unit': 'M'}
We can also use .groups() to list results in a tuple.
res.groups()
Output:
('Revenue (ttm)', '806.43', 'M')
In this case, we'll immediately unpack those results into your variable names.
revenue = None # If this is None after trying to set it, don't print anything.
revenue, revenue_value, revenue_unit = res.groups()
We'll use fancy f-strings to print out both your f.write() call along with the results we've captured.
if revenue:
print(f'f.write(revenue + "," + revenue_value + "," + revenue_unit + "\\n")\n')
print(f'f.write("{revenue}" + "," + "{revenue_value}" + "," + "{revenue_unit}" + "\\n")')
Output:
f.write(revenue + "," + revenue_value + "," + revenue_unit + "\n")
f.write("Revenue (ttm)" + "," + "806.43" + "," + "M" + "\n")

Python formatting: How to insert blank spaces in between array data elements of data type float

I have a question regarding formatting. I am trying to extract relevant data and insert this data into a fortran file. Thankfully, I am using python to accomplish this task. It just so happens that the fortran file is sensitive to the number of spaces between text. So, this brings me to my question. My array array data looks like:
[[ -1.80251269 12.14048223 15.47522331]
[ -2.63865822 13.1656285 15.97462801]
[ -1.76966256 11.35311123 16.13958474]
[ -0.76320052 12.45171386 15.34209158]
[ -2.12634889 11.84315415 14.48020468]]
[[-14.80251269 1.14048223 1.47522331]
[ -2.63865822 13.1656285 15.97462801]
[ -1.76966256 11.35311123 16.13958474]
[ -0.76320052 12.45171386 15.34209158]
[ -2.12634889 11.84315415 14.48020468]]
[[ -0.80251269 0.14048223 0.47522331]
[ -2.63865822 13.1656285 15.97462801]
[ -1.76966256 11.35311123 16.13958474]
[ -0.76320052 12.45171386 15.34209158]
[ -2.12634889 11.84315415 14.48020468]]
These elements are floats, not strings. For example, I wanted the the first row (and every row thereafter) of the data to look like:
-1.80251269 12.14048223 15.47522331
How would I accomplish this? To be specific, there are 5 white spaces that seperate the left margin from the 1st number, -1.80251269, and 5 white spaces that seperate each of the three numbers. Notice also that I need the array brackets gone, but I suspect I can do this with a trim function. Sorry for my lack of knowledge guys; I do not even know how to begin this problem as my knowledge in Python syntax is limited. Any help or tips would be appreciated. Thanks!
EDIT: this is the code I am using to generate the array:
fo = np.genfromtxt("multlines.inp")
data=scipy.delete(fo, 0, 1)
txt = np.hsplit(data,3)
all_data = np.vsplit(data, 4)
i=0
num_molecules = int(raw_input("Enter the number of molecules: "))
print "List of unaltered coordinates:"
while i < (num_molecules):
print all_data[i]
If you are using NumPy, you can use np.savetxt:
np.savetxt('a.txt', a.reshape(15,3), '%16.8f')
To get
-1.80251269 12.14048223 15.47522331
-2.63865822 13.16562850 15.97462801
-1.76966256 11.35311123 16.13958474
...
(You need to reshape your array into 2-dimensions to do what I think you want).
If you have your data formatted as a list, then I suspect that #kamik423's answer will help you. If it if formatted as a string, you may wish to try something like the following.
def properly_format(line):
nums = line.strip(' []\t').split()
spaces = ' '
return spaces + nums[0] + spaces + nums[1] + spaces + nums[2]
lines = my_array_string.splitlines() #if your data is a multiline string
for line in lines:
formatted_line = properly_format(line)
# do something with formatted_line
Edit: forgot to split the string.
If you don't care about the length of each block you can just do
for i in whateverYouArrayIsCalled:
print str(i[0]) + " " + str(i[1]) + " " + str(i[2])
if you however want to have all the elements to be inline try
for i in whateverYouArrayIsCalled:
print (str(i[0]) + " ")[:20] + (str(i[1]) + " ")[:20] + str(i[2])
where the 20 is the length of each block
(for 2.7)
I will assume that the data array is saved in a data.txt file and you want to save the result into fortran.txt, then:
fortran_file = open('fortran.txt','w') # Open fortran.txt for writing
with open('data.txt',r) as data_file: #Open data.txt for reading
while True:
line = data_file.readline()
if not line: break # EOF
result = line.strip('[]').split()
result = " " + " ".join(result)
fortran_file.write(result)
fortran_file.close()
try this:
import numpy
numpy.set_printoptions(sign=' ')

Categories