AS 3600 public comment draft and py_RC Design

A draft of the latest update to AS 3600 (the Australian code for concrete structures) was recently published for public comment (now closed). There are many significant changes to design procedures, and I have updated the py_RC Design spreadsheet to allow some of the new proposed procedures to be used:

  • For ULS design of beams and columns there are minor changes to the current rules for using a rectangular stress block, including increasing the strain at the compression face from 0.003 to 0.0035.
  • Alternatively, a curvilinear-rectangular stress block may be used, with a similar definition to that used in Eurocode 2.
  • The crack width calculation has been modified to take better account of the effects of creep on tensile strains in the concrete.

The new spreadsheet and associated Python code can be downloaded from:

py_RC Design.zip

Also see py_RC Design 2 for more details of the other functions in the spreadsheet, and Python and pyxll for information about the required pyxll add-in, together with a discount voucher for new users.

The spreadsheet has been modified with VBA code to call the LoadRCFunc function at start-up, so this code should be added to the pyxll start-up module:

@xl_macro
@xl_menu("RC Functions", menu="Load")
def LoadRCFunc():
    try:
        imp.import_module('RC_design')
        pyxll.rebind()
        xlcAlert('RC Functions module import completed')
    except:
        xlcAlert('Module not imported')
    return

The Code variable for the py_Umom function has been changed to accept a two cell range as input, specifying the Code and Version numbers. Currently the Version is only used for AS 3600 (Code 1), with the following options:

  • 1 = current code (2018, Amendment 2)
  • 2 = 2026 draft with modified rectangular stress block
  • 3 = 2026 draft with curvilinear-rectangular stress block

Click on any image for full-size view:

The same change to the Code input has been applied to the py_Estress function, with Version =2 specifying the new draft. This currently only affects the results for the calculated crack width:

Posted in Concrete, Excel, Link to Python, Newton, PyXLL, UDFs | Tagged , , , , , , , , , | Leave a comment

Brainteaser and Python sets

The ABC Radio web site has a regular Friday brain teaser:

If you want to solve the problem yourself, read no further because a spoiler follows!

Investigation of the solution to this problem led me to looking at the use of Python sets, which are unordered collections of unique, hashable elements. For the current problem the important properties are:

  • The members are unique, so if you try to add a member that already exists, it won’t change the set.
  • The set is hashable, which means it can be searched very quickly.

For more detailed information on the use of sets see: Real Python – Sets in Python

The solution to the problem is that for each word in the list, if you substitute the first letter with the preceding or following alphabetical letter, it is still an English word. This raised the question: how many English words are there that have this property? To investigate that, first we need a list of all English words, which I found at: Words.alpha.txt

The following Python code creates an Excel user defined function (UDF) that:

  • Opens the selected text file
  • Copies each line to a set called words
  • For each word in words, it removes the first letter and constructs new words starting with the preceding and following letters.
  • If both of the new words are found in the words set, it adds 1 to the total number of qualifying words and all three words to a set called qualifying.
  • Finally it returns the total number of words in the supplied dictionary, the number of qualifying words, and the list of all qualifying words and their neighbours.
@xl_func
@xl_return('numpy_array')
def wordcount(dictfile):
    __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
    with open(os.path.join(__location__, dictfile), encoding='utf-8') as dict :
        words = set()
        for line in dict:
            word = line.strip().lower()
            if word.isalpha():  # Only consider alphabetic words
                words.add(word)

    qualifying = set()
    numwords = 0
    # Find all words that have both a previous and next letter neighbor in the dictionary
    for word in words:
        if len(word) < 2:
            continue
        suffix = word[1:]
        first_letter = ord(word[0])
        previous_letter = first_letter - 1
        if previous_letter >= ord('a'):
            pneighbour = chr(previous_letter) + suffix
            if pneighbour in words:
                next_letter = first_letter + 1
                if next_letter <= ord('z'):
                    nneighbour = chr(next_letter) + suffix
                    if nneighbour in words:
                        numwords += 1
                        qualifying.add(pneighbour)
                        qualifying.add(nneighbour)
                        qualifying.add(word)
    qualifying = sorted(qualifying, key=lambda x: x[1:])  # Sort by the second letter of the word
    rtn = np.zeros((len(qualifying)+2, 1), dtype=object)
    rtn[0, 0] = len(words)
    rtn[1, 0] = numwords
    rtn[2:, 0] = np.array(list(qualifying), dtype=object).reshape(-1)
    return rtn

Output from the UDF.

The UDF output is in column R. I have also copied the results as text and sorted by word length, descending, then alphabetically with the first character removed, then by first character.

Before creating the Python code, I did the same job directly in Excel, without any coding:

The Excel based procedure was:

  • Import the dictionary file as text.
  • Count the letters on each line and sort by size.
  • For words with two or more letters, separate the first letter and the rest of the word in two adjacent columns.
  • Sort by the tail word, then by the first letter.
  • Enter a formula to check for each group of three words if the tail words were the same and the first letters were in alphabetical order (see the formula in Cell F28 in the screenshot).
  • For qualifying groups, enter a 1 in Column F for the central word and in Column G for all three words.
  • Sum the number of qualifying groups, which came to 1596, the same as the Python UDF.
Posted in Excel, Link to Python, PyXLL, UDFs | Tagged , , , , | Leave a comment

py_RC Design with 3D Cache

Following my recent post on passing 3D arrays from Python to Excel I have now added a py_UmomC function to the py_RC Design spreadsheet. The new spreadsheet and Python code, along with related code, can be downloaded from:

py_RC Design.zip

Also see py_RC Design 2 for more details of the other functions in the spreadsheet, and Python and pyxll for information about the required pyxll add-in, together with a discount voucher for new users.

The new py_UmomC function returns all the results from py_Umom as a cache object, which displays the cache name in a single cell. If the results are for a single axial load and/or cross section the cache is 2D, but if the input axial load was an array the cache is a 3D array, with each “sheet” having the results for each axial load value.

The chosen results can be displayed with the py_array3D function. In the example below results are displayed for Column 11, Row 3 (the ultimate shear capacity), and because the Sheet is entered as zero results are returned for all input axial loads:

Changing the Column/Row values to 2 and 4 returns the ultimate bending capacity:

The py_Umom function can also return results for an input array of section depths, optionally with associated reinforcement areas. The axial load may be varying or constant:

As before, different results are returned using the py_Array3D function calling the same cache object with different column and/or row specified:

If the output row is entered as 0 the results are returned as a 2D array, with all the results for the specified column and each axial load in the results columns:

Specifying a single column and sheet returns a column array for the specified axial load, and/or cross section:

and specifying Sheet, Column, and Row returns a single value:

Posted in Arrays, Beam Bending, Concrete, Excel, Link to Python, Newton, NumPy and SciPy, PyXLL, UDFs | Tagged , , , , , , , , , , | 2 Comments

Josh Turner

We haven’t had any Bach posts for a bit, so here is new (to me) guitarist Josh Turner playing a cover of Bert Jansch’s version of Blackwaterside:

and another example of his varied work, a cover of Nick Drake’s Three Hours:

and another Nick Drake cover, One of These Things First:

Posted in Bach | Tagged , , , , | Leave a comment

VBA polynomial functions update

Following several comments at an old post I have made updates to the Polynomial spreadsheet. The new files can be downloaded from:

Polynomial.zip

The changes are:

  • SolvePoly was amended to accept numbers or signed cell addresses in the input.
  • QuarticR, CubicR, QuadraticR and SolvePolyR functions were added, returning only the real roots.
  • SolvePoly was modified to return all real roots before the complex roots, and sort all real roots in ascending order in all cases.
  • The CubiCC was found to have been corrupted at some stage, and was returning incorrect results in some cases. It has been corrected and verified against the SolvePoly function and by checking the returned error values.
  • SolvePoly was modified to allow the first input argument to be either a single row or column range, with any remaining coefficients entered as single cells or values.
  • The Python polynomial functions have been moved to the pyNumpy module.

New functions returning real roots only:

Updated SolvePoly and SolvePolyR:

SolvePoly with an array as the first argument:

Also see Complex Numbers and Solving Quartic Polynomial Equations and Solving higher order polynomials.

For links to the latest Python polynomial functions see Calling Numpy polynomial functions from Excel.

Posted in Excel, Link to Python, Maths, Newton, NumPy and SciPy, PyXLL, UDFs, VBA | Tagged , , , , , , , | Leave a comment