Using a reference to create a new object in python - python

I think that this is a pure Python "problem" but some context is needed:
I'm creating a simple Python script to modify ods documents with the library ezodf.
Ods files are similar to Excel documents: a table containing cells that contain value, format, etc.
The source comes from a template that I can't edit since I don't have the access to it and I need new cells with the same format as the ones I have but creating them with ezodf is not an option.
Let's work just with column "A" to simplify
I want cell["A5"] to be a copy of cell["A3"] but if I do
cell["A5"] = cell["A3"]
the cell "A3" moves to "A5" instead of filling cell "A5" with a copy and I can no longer access "A3"
My question is, what can I do to assign a cell["A5"] to a copy of "A3" instead of assigning it to "A3"?

Thanks to Maksymilian for showing me this module, I've tryied with cell["A5"] = copy.deepcopy(cell["A3"]) to create new cells based on the original "A3" cell and it works like a charm

Related

(python) using a csv file to store details of a map

i am creating a text based game in python. in this, i will be using a CSV file to store the different tiles on the map. i would like to know what code i would need to essentially request the 'co-ordinates' of the map tile.
for example, if i was to create a tile with the co-ordinates x = 5, y = 6; it would store the information (GRASS1S2s1w, for example) in the 5th column and the sixth row.
i would also like to know how to call the specific cell in which the data is stored.
any alternate ways of doing this (not CSV) will be ignored. this is for a school project and i am too far through to change from CSV (i would have to change a lot of words in my plan.)
note: GRASS1S2I3Sc means 'grass tile' (GRASS), "stone" (1S), "scrap" (2S) and "wood" (1W)
Make a 2d list containing all the information. That way you can access a value of a specific coordinate like
list[x][y]
Then save the list with csv.writer
You can read the existing csv file as a list similarly to access the info.

How to use Excel defined names in Python to obtain the values?

I have the following set of code which is trying to find the text in a cell within an excel worksheet called 'Input'. I am using openpyxl.
The cell uses a defined name in excel called 'Rperiod'. I can call the text by specifying the sheet and cell range directly, but I'm wondering if there is a way to use the defined_names function to keep it dynamic.
Rperiod = wb.defined_names['Rperiod']
Rperiod.value
This results in 'Input!$F$8' but then I can't workout if it is possible to use this result to get the text. The static method is:
input_sheet = wb.get_sheet_by_name('Input')
Rperiod_cell = input_sheet['F8']
Rperiod_cell.value
This returns the correct result 'Quarterly' but I obviously want to do this without directly specifying the cell 'F8' or the sheet 'Input'.
Any help is greatly appreciated!

How to copy a formula from one gsheet to another using python?

I'm not sure if this is possible. I have tons of spreadsheet, and the formulas need to be updated. How do I copy a formula from one cell or a group of cells to another? I've used gspread and it seems it can only do values. I need python to basically paste formulas on hundreds of sheets for me, without me opening each individually and copy and pasting the formulas.
Does anybody have a generic solution for copying and pasting formulas? This is pretty important, you would think someone can do it.
Update 19 July 2018:
Here's how you do it:
# Get the formula value from the souce cell:
formula = wks.acell('A2', value_render_option='FORMULA').value
# Update the target cell with formula:
wks.update_acell('B3', formula)
(this works since gspread 3.0.0 which uses Sheets API v4.)
Original answer below:
To access a formula value, you need to use the input_value attribute of a cell object.
Here's an example. (I'm skipping the initialization step. Let's assume you've already opened a spreadsheet and wks is referring to you worksheet object.)
# To copy a formula from a single cell (say, A2) to another cell (B3)
# use the input_value property
formula = wks.acell('A2').input_value
# then paste the value to a new cell
wks.update_acell('B3', formula)
For a group of cells, you'd want to use a wks.range() method to get cell objects. Then you can get formula values via input_value as in the code above. See the example on the GitHub.

How to Check the cell from excel which has formula using python

I Want to access the cell which has formula from the excel workbook.Actually my python script is working fine only to read the data from excel, but i need that only the cell which has formula and to print that cells only
An example would be really appreciated..........
Two things that could help you solve the problem:
There's a typo: HasForumla instead of HasFormula
e is a string, not a cell object, so e.HasFormula won't work.
You probably want to use
e = sheet.cell(row,17)
to access the Cell object at that position. I'm not sure where you got your HasFormula attribute from, though - couldn't find it in the docs.
Edit:
I just looked at the README for the current distribution where it's stated that
xlrd will safely and reliably ignore any of these if present in the
file:
[...]
Formulas (results of formula calculations are extracted, of course).
[...]

python: xlrd/csv - empty cell treatment when xlrd/csv packages read objects into memory

Is there an option to change the default way the csv and xlrd packages handle empty cells? By default empty cells are assigned an empty string value = ''. This is problematic when one is working with databases because an empty string is not a None value, which many python packages that interface with databases (SQLAlchemy for example) can handle as a Null for database consumption.
For example if an empty cell occurred in a field that is suppose to be a decimal/integer/float/double then the database will throw up an exception because an insert of a string was made to a field of type decimal/integer/float/double.
I haven't found any examples or documentation that shows how I can do this. My current approach is to inspect the data and do the following:
if item[i] == '':
item[i] = None
The problem with this is that I don't own the data and have no control over its quality. I can imagine that this would be a common occurrence since a lot of apps are using files/data that are produced by sources other then them.
If there is a way to change the default treatment then that would be a sensible approach in my opinion.
I have the same setup as yourself (sqlalchemy for the ORM, and data that I have little control over, being fed through excel files). I found that I need to curate the data from the xlrd before dumping it in the database. I am not aware of any tweaks that you can apply on the xlrd module.
On a more general note:
It is probably best to try and get as large a sample of example excel files as you can and see if your application can cope with it. I found that occasionally weird characters make it through the excel (people copy paste from different languages) which cause crushes further down. Also found that in some cases the file format was not UTF-8 but iso-8859 or something else. I ended up using iconv for converting the files.
you may also want to have a look at this stackoverflow article
Overall xlrd has worked for us, but I am less than impressed with the activity around the project. Seems like I am using a library that has little maintenance.
You could use the following code to change the values of all empty cells in the sheet you are reading in to NULL (or None, or whatever you like) before you actually read in the data. It loops through all rows and columns and checks if the cell_type is EMPTY and then changes the value of the respective cell to 'NULL'.
import xlrd
book = xlrd.open_workbook("data.xlsx")
sheet_name = book.sheet_names()[0] #getting the sheetname of the first sheet
sheet = book.sheet_by_name(sheet_name)
for r in range(0,sheet.nrows): #create a list with all row numbers that contain data and loop through it
for s in range(0, sheet.ncols): #create a list with all column numbers that contain data and loop through i
if sheet.cell_type(r, c) == xlrd.XL_CELL_EMPTY:
sheet._cell_values[r][c] = 'NULL'
Then you can read in the data (e.g. from the first column) and you will get NULL as a value if the cell was previously empty:
for r in range(0,sheet.nrows):
data_column_1 = sheet.cell(r,0).value
xlrd will tell you what type of cell you have (empty or blank, text, number, date, error).
This is covered in the xlrd documentation. Look at the Cell class, and these methods of the Sheet class: cell_type, col_types, and row_types.
The csv format has no way of expressing the difference between "no data at all" and "the value is a zero-length string". You will still need to check for '' and act accordingly.

Categories