def mm_ampersand(): """ Manually read the database (Edit the function for results)""" import modules.x_misc as misc import modules.x_database as db # Work out a name of the file sFile_path = "Logs/db_read.txt" eDb_read = open(sFile_path, "w", encoding="utf-8") # Read all the geographic data if False: # Do the query xParam = { "aDemand_workforce.aItemised.sName": "wheat farm" } # All queries xRestr = {"_id": 0, "geo_code": 1, "aDemand_workforce.aItemised": 1} ccTremb = db.connect() cDb_of_choice = db.destinations(ccTremb) dQuery = cDb_of_choice.find(xParam, xRestr) # Read data in chronographic order if False: # Do the query xParam = {} # All queries xRestr = {"_id": 1, "my_id": 1, "host_geo_code": 1} ccTremb = db.connect() cDb_of_choice = db.housing(ccTremb) dQuery = cDb_of_choice.find(xParam, xRestr) dQuery = dQuery.distinct("host_geo_code") # Pulls out single element dQuery.sort() # Sort modifies in place. Returns 'none' # Read all the data if True: # Do the query xParam = {} # All queries xRestr = {"_id": 0} ccTremb = db.connect() cDb_of_choice = db.maps_db(ccTremb) dQuery = cDb_of_choice.find(xParam, xRestr) for x in dQuery: print(x) eDb_read.write("{0}\n".format(x)) eDb_read.close()
def calc_timetable(ccTremb): """ This method calculates the approximate time for the train to travel between the two specified points. """ # Open the 'lines' database. cLines = db.lines(ccTremb) cDest = db.destinations(ccTremb) sLine = "K00-001" # Obtain the travel durations. dSta_jct = calc_pax(cLines, sLine) if dSta_jct == None: return None if len(dSta_jct) < 1: return None # Process the array aKeys = dSta_jct[0].keys() sAll = "" sSep = ";" sAll += "km{0}type{0}code{0}name{0}s away{0}s home\n".format(sSep) for item in dSta_jct: fKm = item["km"] sType = item["type"] code = item["code"] sLat = " " if sType == "sta" and code != None: aNames = misc.verify_geo_code(code, cDest, bDont_warn=True) if aNames != None: sLat = aNames["lat"] away = item["away"] home = item["home"] sTxt = "{1}{0}{2}{0}{3}{0}{4}{0}{5}{0}{6}\n" sTxt = sTxt.format(sSep, fKm, sType, code, sLat, away, home) sAll += sTxt # Write this data to a .csv file (to be used with excel) sFile_path = "Logs/travel_{0}.csv".format(sLine) eTravel = open(sFile_path, "w", encoding="utf-8") eTravel.write(sAll) eTravel.close() print("Please see {0}".format(sFile_path)) return True
def pretty_print_single(ccTremb): """ Writes most of the elements from the database in a human-readable format """ import datetime sMenu = "\nPlease Enter the housing identifier (ex: H00-001)" print(sMenu) sHse_code = input().upper() # Force to upper case (consistency) # Access the database. cHouse = db.housing(ccTremb) xParam = {"my_id": sHse_code} xRestr = {"_id": 0} dQuery = cHouse.find(xParam, xRestr) # Pull the data and verify the existance iNo_of_hits = 0 dData = "" for query in dQuery: dData = query iNo_of_hits += 1 if iNo_of_hits != 1: sTxt = ("\n\aThere were {0} 'hits' while expecting 1 for [{1}]") print(sTxt.format(iNo_of_hits, sHse_code)) return None # Work out a name of the file sFile_path = "Logs/h_{0}_pretty.txt".format(sHse_code) eSingle_data = open(sFile_path, "w", encoding="utf-8") # Write the title with timestamp sAll = "" # Clean state xNow = datetime.datetime.now() sAll += "Pretty print Housing request was generated on {0}\n".format(xNow) # Identifiation information sAll += "----------\n" sAll += "my_id: {0}\n".format(dData["my_id"]) # Name of the block / Area sName_lat = dData["aName"]["lat"] sName_cyr = dData["aName"]["cyr"] sAll += "Name: '{0}' / '{1}'\n".format(sName_lat, sName_cyr) # Host identification sGeo_code = dData["host_geo_code"] cDest = db.destinations(ccTremb) # Database of host aName = misc.verify_geo_code(sGeo_code, cDest) sAll += "----------\n" sLat = aName["lat"] sCyr = aName["cyr"] sTxt = "Host: [{0}] '{1}' / '{2}'\n" sTxt = sTxt.format(sGeo_code, sLat, sCyr) sAll += sTxt # MAP: sAll += "----------\n" sAll += "Map and area: \n" aMap = dData["aMap"] if aMap["sRegion"] != "No Map": iScale = int(aMap["fScale"]) sTxt = "> Region: {0} 1:{1:,} (drawn in {2})\n" sAll += sTxt.format(aMap["sRegion"], iScale, aMap["iYear"]) sTxt = "> Position (mm) x: {0}, y: {1}\n" sAll += sTxt.format(aMap["x"], aMap["y"]) sTxt = "> Area on paper (sq.mm) a: {0:,}\n" sAll += sTxt.format(aMap["a"]) else: sAll += "> No map declared\n" # More about the buildings sAll += "----------\n" sAll += "Building(s):\n" sAll += "> Description: {0}\n".format(dData["sDesc"]) sAll += "> Type: {0}\n".format(dData["type"]) sAll += "> Sub-type: {0}\n".format(dData["sub_type"]) sAll += "> Demographic code: '{0}'\n".format(dData["demographic"]) sAll += "> Units per floor: {0}\n".format(dData["iUnits_per_floor"]) sAll += "> Number of floors: {0}\n".format(dData["iNo_of_floors"]) sAll += "> Number of buildings: {0}\n".format(dData["iNo_of_buildings"]) sAll += "> Total units: {0}\n".format(dData["iTot_units"]) # Building footprint, if data is available fQty = dData["aFpt_bldg"]["qty"] sUom = dData["aFpt_bldg"]["uom"] sTxt = "> Building footprint: " if fQty == None: sTxt += "N/A\n" else: sTxt += "{0:,}{1}\n".format(fQty, sUom) sAll += sTxt # Property footprint, if data is available fQty = dData["aArea_plot"]["val"] sUom = dData["aArea_plot"]["uom"] sTxt = "> Area of plot: " if fQty == None: sTxt += "N/A\n" else: sTxt += "{0:,}{1}\n".format(fQty, sUom) sAll += sTxt # More about the parking situation aParking = dData["aParking"] sAll += "----------\n" sAll += "Parking (cars):\n" sAll += "> Levels: {0}\n".format(aParking["iFloors"]) sAll += "> Total vehicle spaces: {0}\n".format(aParking["iVeh"]) sAll += "> Area on map: {0}sq.mm\n".format(aParking["map_a"]) # Write to the file print("Please see: {0}".format(sFile_path)) eSingle_data.write("{0}\n".format(sAll)) eSingle_data.close()
def add_housing(ccTremb): """ Adds details of the housing to the database """ # Obtain the highest "my_id" code that is registered in the database. xParam = {} xRestr = {"_id": 0, "my_id": 1} cHousing = db.housing(ccTremb) dId_query = cHousing.find(xParam, xRestr) iHighest, aEvery_id = misc.find_highest_id(dId_query) if (False): # Debugging sTxt = "\n\nHighest number is {0}(10) < < < < < < < <" print(sTxt.format(iHighest)) # We do have the highest identifier (expressed as a decimal number). Hence, # we can incerement the sequence and use it. iNext_id = iHighest + 1 if iNext_id > 36**5: print("\n\aMaximum count has been exceeded") return None # Convert to base36 sBase36 = misc.base_conv(iNext_id) sBase36_5 = sBase36.rjust(5, "0") # "0002W" -> "D00-02W" sNew_id = "H{0}-{1}".format(sBase36_5[:2], sBase36_5[2:]) print("\nNext id is {0}".format(sNew_id)) # START GETTING THE USER TO ENTER THE NEW DATA. # Open a blank dictionary, so that the elements are arranged in a certain # order. dNew_housing = { "my_id": sNew_id, "host_geo_code": None, "aName": { "lat": None, "cyr": None }, # Is the block of flats named? "type": None, # Green(space), Res(idential) "sub_type": None, # house, lin apt, sq apt, x apt, irreg apt, "iUnits_per_floor": 0, # How many apartments in the block "iNo_of_floors": 1, # How tall is the building "iNo_of_buildings": 1, # How many buildings in the 'package' "iTot_units": 0, # Total households in this location "sDesc": "", # Description ex: "9x2x1M; 9 = 7+1S+1SP" "demographic": "", # 'r' to 'p' "aParking": { "iFloors": 1, # How many levels is parking offered on. "iVeh": 0, # Vehicles in total "map_a": 0, # sq.mm on the map per floor of the parking area. }, "aMap": { "sRegion": None, "iYear": None, "fScale": None, "x": None, "y": None, "a": None }, "aFpt_bldg": { "qty": None, "uom": None }, "aArea_plot": { "qty": None, "uom": None }, } # Automatically obtain the geo-code of the last entry. Chances are that we'd # like to re-use it. xParam = {} xRestr = {"_id": 0, "host_geo_code": 1} dId_query = cHousing.find(xParam, xRestr).sort("_id", 1) dId_query.sort("_id", -1) # Pull out the geo-code sGeo_code = dId_query[0]["host_geo_code"] cDest = db.destinations(ccTremb) dGeo_names = misc.verify_geo_code(sGeo_code, cDest) if dGeo_names == None: return None # An error has occured. # Names of the settlement. sP_lat = dGeo_names["lat"] sP_cyr = dGeo_names["cyr"] sTxt = "Are you working on {0} ({1} / {2})?" sTxt = sTxt.format(sGeo_code, sP_lat, sP_cyr) yn_last_host = misc.get_binary(sTxt) if yn_last_host == None: return None if yn_last_host == "N": # HOST sTxt = ("\nWho is hosting this residential area OR greenspace?\n" + "Please enter host's geo-code.") print(sTxt) sGeo_code = input().upper() dGeo_element = misc.get_geo_element(sGeo_code, cDest) if dGeo_element == None: return aHost_name = dGeo_element["aName"] dNew_housing["host_geo_code"] = sGeo_code sTxt = "\nHosted by {0} / {1}".format(aHost_name["lat"], aHost_name["cyr"]) print(sTxt) # TYPE sMenu = "\n" sMenu += "What type area is it?\n" sMenu += "0: Greenspace (Park)\n" sMenu += "1: Residential\n" iType_option = misc.get_int(sMenu, 1) if iType_option == None: print("\a") return None if iType_option == 0: dNew_housing["type"] = "Green" elif iType_option == 1: dNew_housing["type"] = "Res" else: print("\n\aInvalid choice for area type type") return # SUB-TYPE: if dNew_housing["type"] == "Res": # Residential: sMenu = "\n" sMenu += "Type of housing is it?\n" sMenu += "0: House: Free-standing building for 1 or 2 households\n" sMenu += "1: Apartments, Linear: Straight block of appartments\n" sMenu += "2: Apartments, Square: Square-edged Doughnut-shaped bldg\n" sMenu += "3: Apartments, Cross: Cross-shaped building\n" sMenu += "4: Apartments, Irregular: Irregularly-shaped building\n" sMenu += "5: Other: Something rare, or that doesn't fit above descr.\n" iType_option = misc.get_int(sMenu, 5) if iType_option == None: print("\a") return None if iType_option == 0: dNew_housing["sub_type"] = "house" elif iType_option == 1: dNew_housing["sub_type"] = "lin apt" elif iType_option == 2: dNew_housing["sub_type"] = "sq apt" elif iType_option == 3: dNew_housing["sub_type"] = "x apt" elif iType_option == 4: dNew_housing["sub_type"] = "irrg apt" elif iType_option == 5: dNew_housing["sub_type"] = "other" else: print("\n\aInvalid choice for port type") return # Greenspace was selected else: dNew_housing["sub_type"] == "N/A" # MAP REFERENCE sMap = "plot" dData = misc.get_map_input(ccTremb, sMap) # Asks for user to input stuff. if dData in [None, True]: # No map selected print("\n\aInvalid entry from the map. Exiting") return None # Transfer data through. dNew_housing["aMap"] = dData["dMap"] dNew_housing["aArea_plot"] = dData["dArea"] # BUILDING SIZE if dNew_housing["type"] == "Res" and dNew_housing["sub_type"] != "house": sTxt = "\nEnter the footprint of the building in sq.mm from map." fBldg_ftp = misc.get_float(sTxt) if fBldg_ftp == None: return None # Calculate area fScale = dNew_housing["aMap"]["fScale"] dNew_housing["aFpt_bldg"] = misc.calc_area(fBldg_ftp, fScale) # OPTIONAL NAME aName = misc.building_name() if aName == None: return None if aName != False: # False: if a name was not chosen dNew_housing["aName"] = aName # DEMOGRAPHICS: sMenu = "\n" sMenu += "Which demographic is residing here?\n" sMenu += "0: Rich [2500sq.m plot and up]\n" sMenu += "1: High-income [1600sq.m plot]\n" sMenu += "2: Mid-income [ 900sq.m plot]\n" sMenu += "3: Low-income [ 600sq.m plot]\n" sMenu += "4: Poor [ 400sq.m plot]\n" iLevel_option = misc.get_int(sMenu, 4) if iLevel_option == None: print("\a") return None if iLevel_option == 0: dNew_housing["demographic"] = "r" elif iLevel_option == 1: dNew_housing["demographic"] = "h" elif iLevel_option == 2: dNew_housing["demographic"] = "m" elif iLevel_option == 3: dNew_housing["demographic"] = "l" elif iLevel_option == 4: dNew_housing["demographic"] = "p" else: print("\n\aInvalid choice for port type") return # DESCRIPTION: sTxt = ("\nGive a brief description of the area. For example:\n" + "'(9x2)x1M [7+1S+1SP]': Seven units in a row, 1 from the side, " + "1 panhandle from\nside with two households sharing this building") print(sTxt) dNew_housing["sDesc"] = input() # BUILDING COUNT sTxt = ("\nHow many buildings in the group?") iNo_of_buildings = misc.get_int(sTxt) if iNo_of_buildings == None: return None dNew_housing["iNo_of_buildings"] = iNo_of_buildings # FLOOR COUNT sTxt = ("\nHow many floors does each building have?") iFloor_cnt = misc.get_int(sTxt) if iFloor_cnt == None: return None dNew_housing["iNo_of_floors"] = iFloor_cnt # APPARTMENT COUNT sTxt = ("\nHow many appartments per floor in this building?") iUnits_per_floor = misc.get_int(sTxt) if iUnits_per_floor == None: return None dNew_housing["iUnits_per_floor"] = iUnits_per_floor # TOTAL UNITS fTot_units = iNo_of_buildings * iFloor_cnt * iUnits_per_floor iTot_units = int(round(fTot_units, 0)) dNew_housing["iTot_units"] = iTot_units # PARKING: sMenu = "\n" sMenu += "How do you want to calculate car parking available?\n" sMenu += "0: Individual houses, with x number of cars per plot\n" sMenu += "1: Square footprint, with x and y known in mm.\n" sMenu += "2: Footprint, with area in sq.mm is known\n" iParking_option = misc.get_int(sMenu, 2) if iParking_option == None: return None iVeh = None # I publish the results of the parking. # INDIVIDUAL HOUSES if iParking_option == 0: sTxt = ("There are {0} plots in this area. Enter number of vehicles " + "per plot\nthat can be parked off the street. (Usually 2)") sTxt = sTxt.format(iNo_of_buildings) iVeh = misc.get_int(sTxt) if iVeh == None: return None iVeh *= iNo_of_buildings dNew_housing["aParking"]["iVeh"] = iVeh # SQUARE FOOTPRINT KNOWN SIDES elif iParking_option == 1: sTxt = ("Enter the first side of the area for parking") fParking_x = misc.get_float(sTxt) if fParking_x == None: return None sTxt = ( "Enter the second side of the area for parking, perpendicular" + " to the first") fParking_y = misc.get_float(sTxt) if fParking_y == None: return None # Calculate the parking area fMap_area = fParking_x * fParking_y fMap_scale = dNew_housing["aMap"]["fScale"] aParking_area = misc.calc_area(fMap_area, fMap_scale) if aParking_area == None: return None # We know the real-world scale of the parking. # In the real world, a parking bay is 5.5m x 2.5m (13.75sq.m). However, # each vehicle needs access to that bay. The above calcuation gives # 7.27veh/100sq.m. However, each vehilce needs some space to get to the # bay. Hence, I'm using the figure of 6 veh / 100sq.m (600veh/ha) # Verify the units of measurement if aParking_area["uom"] != "sq.m": print( "\nUnexpected calculation result for residential parking:\n" + "Expected 'sq.m', but got {0}\a".format(aParking_area["uom"])) return None fSqm_P = aParking_area["qty"] sTxt = ("On how many levels are cars parked?") iFloors = misc.get_int(sTxt) if iFloors == None: return None if iFloors > 1 and fSqm_P < 90: sTxt = ("\n\aInsufficient space for a ramp " + "(1:10 @ h = 3.6m, w = 2.5m). Exiting") return None if iFloors > 1: fSqm_P -= 90 # Take room for the ramp fVeh = 6.0 * fSqm_P / 100 # 6 cars per 100 sq.m print("fVeh:{0}; fSqm_P:{1}".format(fVeh, fSqm_P)) iVeh = int(round(fVeh, 0)) # Round off to whole vehicles fVeh = iVeh * iFloors # We need to round off per floor. iVeh = int(round(fVeh, 0)) # Round off to whole vehicles fVeh = iVeh * iNo_of_buildings # Parking in each building iVeh = int(round(fVeh, 0)) # Round off to whole vehicles dNew_housing["aParking"]["iFloors"] = iFloors dNew_housing["aParking"]["iVeh"] = iVeh dNew_housing["aParking"]["map_a"] = fMap_area # BASEMENT PARKING: FOOTPRINT AREA KNOWN elif iParking_option == 2: sTxt = ("Enter the area of the parking footprint in sq.mm from map.") fMap_area = misc.get_float(sTxt) if fMap_area == None: return None # Calculate the parking area fMap_scale = dNew_housing["aMap"]["fScale"] aParking_area = misc.calc_area(fMap_area, fMap_scale) if aParking_area == None: return None # We know the real-world scale of the parking. # In the real world, a parking bay is 5.5m x 2.5m (13.75sq.m). However, # each vehicle needs access to that bay. The above calcuation gives # 7.27veh/100sq.m. However, each vehilce needs some space to get to the # bay. Hence, I'm using the figure of 6 veh / 100sq.m (600veh/ha) # Verify the units of measurement if aParking_area["uom"] != "sq.m": print( "\nUnexpected calculation result for residential parking:\n" + "Expected 'sq.m', but got {0}\a".format(aParking_area["uom"])) return None fSqm_P = aParking_area["qty"] print("Parking is: {0}{1}".format(aParking_area["qty"], aParking_area["uom"])) sTxt = ("On how many levels are cars parked?") iFloors = misc.get_int(sTxt) if iFloors == None: return None if iFloors > 1 and fSqm_P < 90: sTxt = ("\n\aInsufficient space for a ramp " + "(1:10 @ h = 3.6m, w = 2.5m). Exiting") return None if iFloors > 1: fSqm_P -= 90 # Take room for the ramp fVeh = 6.0 * fSqm_P / 100 iVeh = int(round(fVeh, 0)) # Round off to whole vehicles fVeh = iVeh * iFloors # We need to round off per floor. iVeh = int(round(fVeh, 0)) # Round off to whole vehicles fVeh = iVeh * iNo_of_buildings # Parking in each building iVeh = int(round(fVeh, 0)) # Round off to whole vehicles dNew_housing["aParking"]["iFloors"] = iFloors dNew_housing["aParking"]["iVeh"] = iVeh dNew_housing["aParking"]["map_a"] = fMap_area # Save the data in the array print("\nThese buildings park {0} vehicles".format(iVeh)) # -- -- -- -- -- -- -- -- -- -- # UPDATE THE GEO-OBJECT dSup_hhold = dGeo_element["aSupply_hholds"] # Get the existing data out dTot_sup = dSup_hhold["total"] aItemised = dSup_hhold["aItemised"] # Update total of this particular demographic sGroup = dNew_housing["demographic"] # 'r' to 'p' iTot_units = dNew_housing["iTot_units"] # Household count. dTot_sup[sGroup] += iTot_units # Add to the grand total # Generate the prototype dItem = {"sName": None, "r": 0, "h": 0, "m": 0, "l": 0, "p": 0} # Update the item dItem["sName"] = dNew_housing["my_id"] # > 36 blocks possible dItem[sGroup] += iTot_units # Build the item aItemised.append(dItem) # Save with suburb # UPDATE DATA BASE cHousing.insert_one(dNew_housing) # Housing pushed # UPDATE HOST xParam = {"geo_code": sGeo_code} xNew_data = {"$set": {"aSupply_hholds": dSup_hhold}} cDest.update_one(xParam, xNew_data) print("\n DATABASE ENTRIES UPDATED ({0})".format(sNew_id))
def pretty_print_single(ccTremb): """ Writes most of the elements from the database in a human-readable format """ import datetime sMenu = "\nPlease Enter the station identifier (ex: S00-001)" print(sMenu) sSta_code = input().upper() # Force to upper case (consistency) # Access the database. cStation = db.stations(ccTremb) xParam = {"my_id": sSta_code} xRestr = {"_id": 0} dQuery = cStation.find(xParam, xRestr) # Pull the data and verify the existance iNo_of_hits = 0 dData = "" for query in dQuery: dData = query iNo_of_hits += 1 if iNo_of_hits != 1: sTxt = ("\n\aThere were {0} 'hits' while expecting 1 for [{1}]") print(sTxt.format(iNo_of_hits, sSta_code)) return None # Work out a name of the file sFile_path = "Logs/s_{0}_pretty.txt".format(sSta_code) eSingle_data = open(sFile_path, "w", encoding="utf-8") # Write the title sName_lat = dData["aName"]["lat"] sName_cyr = dData["aName"]["cyr"] sAll = " {0}\n {1}\n".format(sName_lat, sName_cyr) sAll += "----------\n" # Add the timestamp xNow = datetime.datetime.now() sAll += "Pretty print information was generated on {0}\n".format(xNow) # Identifiation information sAll += "----------\n" sAll += "my_id: {0}\n".format(dData["my_id"]) # Type and sub_type information sLvl = dData["level"] sLong = "" sLvl_info = "" if sLvl == "Int'l": sLong = "International" sLvl_info = "['0V9'->'0Q1']" elif sLvl == "Nat'l": sLong = "National / Inter-Provincial" sLvl_info = "['V'->'L']" elif sLvl == "Prov.": sLong = "Provincial / Inter-District" sLvl_info = "['GY'->'VA']" elif sLvl == "Dist.": sLong = "District / Inter-County" sLvl_info = "['GYN'->'GY0']" elif sLvl == "Cnty.": sLong = "County / Inter-Municipal" sLvl_info = "['GYN-2'->'GYN-0']" elif sLvl == "Muni.": sLong = "Municipal / Intra-Municipal" sLvl_info = "['VAA-0A'->'VAA-0B']" else: pass sAll += "----------\n" sTxt = "Type: {0} {1}: {2}\n" sTxt = sTxt.format(sLong, dData["type"], dData["sub_type"]) sAll += sTxt sAll += "Route example: {0}\n".format(sLvl_info) # MAP: sAll += "----------\n" sAll += "Map and area: \n" aMap = dData["aMap"] if aMap["sRegion"] != "No Map": iScale = int(aMap["fScale"]) sTxt = "> Region: {0} 1:{1:,} (drawn in {2})\n" sAll += sTxt.format(aMap["sRegion"], iScale, aMap["iYear"]) sTxt = "> Position (mm) x: {0}, y: {1}\n" sAll += sTxt.format(aMap["x"], aMap["y"]) sTxt = "> Area on paper (sq.mm) a: {0:,}\n" sAll += sTxt.format(aMap["a"]) aArea = dData["aArea"] sTxt = "> Area represented: {0:,}{1}\n" sAll += sTxt.format(aArea["val"], aArea["uom"]) else: sAll += "> No map declared\n" # Services: lServices = dData["lServices"] sAll += "----------\n" sAll += "Services: \n" cDest = db.destinations(ccTremb) # To get the names of the villages. for sServed in lServices: aName = misc.verify_geo_code(sServed, cDest) # Fetches the names. sTxt = "> [{0}] {1} / {2}\n" sAll += sTxt.format(sServed, aName["lat"], aName["cyr"]) if len(lServices) < 1: sAll += "> N/A\n" # Warehouse: lWarehouse = dData["lWarehouse"] sAll += "----------\n" sAll += "Loading zones: {0}\n".format(dData["iLoading_zones"]) sAll += "Resources transported:\n" for dResource in lWarehouse: sName = dResource["resource"] fQty = dResource["weekly_output"] sUnits = dResource["units"] sAll += "> {0}: {1}{2}\n".format(sName, fQty, sUnits) # Write to the file print("Please see: {0}".format(sFile_path)) eSingle_data.write("{0}\n".format(sAll)) eSingle_data.close()
def mm_star(): """ Tests a concept (This is a scratch pad, or a place to fix mistakes) """ import modules.x_database as db # Delete a single entry if False: xParam = {"dVal.id": 115} xRestr = {} ccTremb = db.connect() cDatabase = db.lines(ccTremb) dQuery = cDatabase.delete_one(xParam, xRestr) print("Specified element deleted") # Delete an entire collection if False: ccTremb = db.connect() cRnd_man = db.rnd_suffix_surname(ccTremb) dQuery = cRnd_man.delete_many({}) print(dQuery.deleted_count, " deleted items!") # Update an array if False: xParam = {"geo_code": "TJV"} # Vaenesston district xNew_data = { "$set": { "aChildren": [ "D00-09I", "D00-09J", "D00-0CM", "D00-0CN", "D00-0CO", ] } } # Prepare the update ccTremb = db.connect() cDest = db.destinations(ccTremb) dParent_query = cDest.update_one(xParam, xNew_data) # Update a bad complex value if False: dNew_data = { 'resource': 'chicken', 'annual_output': 15356, 'units': 't/yr' } xParam = {"my_id": "D00-017"} xNew_data = {"$set": {"aWarehouse.chicken farm 0": dNew_data}} ccTremb = db.connect() cDb = db.destinations(ccTremb) dQuery = cDb.update_one(xParam, xNew_data) # Delete all the geo-codes if False: parent_my_id = "D00-0AL" # Edit me. # Data base connection and selection ccTremb = db.connect() cDb = db.destinations(ccTremb) # Get the parent so we can access the children xParam = {"my_id": parent_my_id} xRestr = {"_id": 0, "aChildren": 1} dQuery = cDb.find(xParam, xRestr) # Analyse the query aChildren = [] for query in dQuery: aChildren = query["aChildren"] # copy out # Erase each child's geo-code for child in aChildren: xParam = {"my_id": child} xNew_data = {"$set": {"geo_code": None}} dQuery = cDb.update_one(xParam, xNew_data) # Global change to the structure if False: dNew_data = { "total": { "rm": 0, "rf": 0, "hm": 0, "hf": 0, "mm": 0, "mf": 0, "lm": 0, "lf": 0, "pm": 0, "pf": 0 }, "aItemised": [], } xParam = {} xNew_data = {"$set": {"aSupply_workforce": dNew_data}} ccTremb = db.connect() cDb = db.destinations(ccTremb) dQuery = cDb.update_many(xParam, xNew_data) # Update a bad simple value if False: dNew_data = "Fusþton" xParam = {'sRegion': 'Loggers Crossing'} # xNew_data = {"$set": {"aVehicles.aItemised.Blàhim" : dNew_data}} xNew_data = {"$set": {'sRegion': dNew_data}} ccTremb = db.connect() cDb = db.maps_db(ccTremb) dQuery = cDb.update_one(xParam, xNew_data) # dQuery = cDb.update_many(xParam, xNew_data) # delete an element if False: xParam = {"geo_code": "GYG"} xNew_data = {"$unset": {"aDemogfx_item": 0, "aWhs_item": 0}} ccTremb = db.connect() cDb = db.destinations(ccTremb) dQuery = cDb.update_one(xParam, xNew_data) # Oblitorate everything except the name, children, area data. # Basically, erase balancing when it was not required. if False: xParam = {"geo_code": "VXA-J"} # Vaenesston district xNew_data = { "$set": { # 'aMap': { # 'sRegion': 'Vænesston', # 'iYear': '2019', # 'fScale': 2000000.0, # 'x': None,'y': None,'a': None}, "aDemand_workforce": { "total": { "rm": 0, "rf": 0, "hm": 0, "hf": 0, "mm": 0, "mf": 0, "lm": 0, "lf": 0, "pm": 0, "pf": 0 }, "aItemised": [] }, "aSupply_workforce": { "total": { "rm": 0, "rf": 0, "hm": 0, "hf": 0, "mm": 0, "mf": 0, "lm": 0, "lf": 0, "pm": 0, "pf": 0 }, "aItemised": [] }, "aDemand_hholds": { "total": { "r": 0, "h": 0, "m": 0, "l": 0, "p": 0 }, "aItemised": [] }, "aSupply_hholds": { "total": { "r": 0, "h": 0, "m": 0, "l": 0, "p": 0 }, "aItemised": [] }, "aDemographics": {}, "aVehicles": {}, "aFootprint": {}, "aWarehouse": {} } } # Prepare the update ccTremb = db.connect() cDest = db.destinations(ccTremb) dParent_query = cDest.update_one(xParam, xNew_data)
def add_station(ccTremb): """ Adds details of a station to the database """ # Obtain the highest "my_id" code that is registered in the database. # Get a list of all the registered base-36 codes xParam = {} xRestr = {"_id": 0, "my_id": 1} cStation = db.stations(ccTremb) dId_query = cStation.find(xParam, xRestr) iHighest, aEvery_id = misc.find_highest_id(dId_query) if (False): # Debugging sTxt = "\n\nHighest number is {0}(10) < < < < < < < <" print(sTxt.format(iHighest)) # We do have the highest identifier (expressed as a decimal number). Hence, # we can incerement the sequence and use it. iNext_id = iHighest + 1 if iNext_id > 36**5: print("\n\aMaximum count has been exceeded") return None # Convert to base36 sBase36 = misc.base_conv(iNext_id) sBase36_5 = sBase36.rjust(5, "0") # "0002W" -> "D00-02W" sNew_id = "S{0}-{1}".format(sBase36_5[:2], sBase36_5[2:]) # START GETTING THE USER TO ENTER THE NEW DATA. # Open a blank dictionary, so that the elements are arranged in a certain # order. dNew_port = { "my_id": sNew_id, "host_geo_code": None, "aName": { "lat": None, "cyr": None }, "type": None, "sub_type": None, "level": None, "aMap": { "sRegion": None, "iYear": None, "fScale": None, "x": None, "y": None, "a": None }, "aArea": { "qty": None, "uom": None }, "lServices": [], "lWarehouse": [], "iLoading_zones": 0, } # HOST cDest = db.destinations(ccTremb) # To verify the geocode sTxt = ("\nWho is hosting this station/port? Please enter thier geo-code.") print(sTxt) sGeo_code = input().upper() aHost_name = misc.verify_geo_code(sGeo_code, cDest) if aHost_name == None: return dNew_port["host_geo_code"] = sGeo_code sTxt = "\nHosted by {0} / {1}".format(aHost_name["lat"], aHost_name["cyr"]) print(sTxt) # TYPE sMenu = "\n" sMenu += "What type of a station or port is it?\n" sMenu += "0: Rail\n" sMenu += "1: Road\n" sMenu += "2: Water\n" sMenu += "3: Air\n" iType_option = misc.get_int(sMenu, 3) if iType_option == None: print("\a") return None if iType_option == 0: dNew_port["type"] = "Rail" elif iType_option == 1: dNew_port["type"] = "Road" elif iType_option == 2: dNew_port["type"] = "Water" elif iType_option == 3: dNew_port["type"] = "Air" else: print("\n\aInvalid choice for port type") return # SUB-TYPE sMenu = "\n" sMenu += "What is transported?\n" sMenu += "0: Passangers (PAX)\n" sMenu += "1: Freight (F)\n" sMenu += "2: Livestock (L/S)\n" iType_option = misc.get_int(sMenu, 2) if iType_option == None: print("\a") return None if iType_option == 0: dNew_port["sub_type"] = "Pax" elif iType_option == 1: dNew_port["sub_type"] = "Freight" elif iType_option == 2: dNew_port["sub_type"] = "Livestock" else: print("\n\aInvalid choice for port type") return # LEVEL sMenu = "\n" sMenu += "What level is the station or port on?\n" sMenu += "0: International ['0V9'->'0Q1']\n" sMenu += "1: National / Inter-Provincial ['V'->'L']\n" sMenu += "2: Provincial / Inter-District ['GY'->'VA']\n" sMenu += "3: District / Inter-County ['GYN'->'GY0']\n" sMenu += "4: County / Inter-Municipal ['GYN-2'->GYN-0] \n" sMenu += "5: Municipal / Intra-Municipal ['VAA-0A'->'VAA-0B'])\n" iLevel_option = misc.get_int(sMenu, 5) if iLevel_option == None: print("\a") return None if iLevel_option == 0: dNew_port["level"] = "Int'l" elif iLevel_option == 1: dNew_port["level"] = "Nat'l" elif iLevel_option == 2: dNew_port["level"] = "Prov." elif iLevel_option == 3: dNew_port["level"] = "Dist." elif iLevel_option == 4: dNew_port["level"] = "Cnty." elif iLevel_option == 5: dNew_port["level"] = "Muni." else: print("\n\aInvalid choice for port type") return # MAP REFERENCE # Obtain the reference to the CAD map. The maps available have their own # database entry cMaps = db.maps_db(ccTremb) xParam = {} xRestr = {"_id": 0} dMap_query = cMaps.find(xParam, xRestr) iNo_of_maps = 0 dMap_copy = [] for dMap in dMap_query: iNo_of_maps += 1 dMap_copy.append(dMap) # Setup a menu of the maps available # Setup an option of entering a region which is not mapped print("\nOn which map is this station/port?") sMenu = "0: No map\n" iCnt = 0 # Go through all the available maps. for one_map in dMap_copy: iCnt += 1 # xScale = "{:.1e}".format(one_map["fScale"]) # 1.0e6 for 1:1M xScale = "{0:,}".format(int(one_map["fScale"])) # Commas every 1000's sTxt = "{0}: {1}, {2} 1:{3}\n" sMenu += sTxt.format(iCnt, one_map["sRegion"], one_map["iYear"], xScale) sMenu += "x: Invalid choice will exit this sub menu" print(sMenu) # Get the response from the user, with reference to the menu being offered. sInput = input() if sInput.isnumeric() == False: # An inbuilt 'abort' system where the user can enter 'x' to exit. print("\nInput is not a numeric value. Returning to menu") return None # Get the details from the dictionary and write them into the destinations # entry. iInput = int(sInput) if (iInput == 0): dNew_port["aMap"]["sRegion"] = "No Map" dNew_port["aMap"]["iYear"] = None dNew_port["aMap"]["fScale"] = None elif (iInput > iCnt): print("\nChoice out of range. Returning to menu") return None else: iIdx = iInput - 1 dNew_port["aMap"]["sRegion"] = dMap_copy[iIdx]["sRegion"] dNew_port["aMap"]["iYear"] = dMap_copy[iIdx]["iYear"] dNew_port["aMap"]["fScale"] = dMap_copy[iIdx]["fScale"] # Map location: Co-ordinates on the speciied CAD map. if (dNew_port["aMap"]["fScale"] != None): # This only works if the map exists. sQuestion = "\nEnter the x-coordinate from the map:" fX = misc.get_float(sQuestion, None, True) if fX == None: return None dNew_port["aMap"]["x"] = fX sQuestion = "\nEnter the y-coordinate from the map:" fY = misc.get_float(sQuestion, None, True) if fY == None: return None dNew_port["aMap"]["y"] = fY sQuestion = "\nEnter the area in mm2 from the map:" fA = misc.get_float(sQuestion) if fA == None: return None dNew_port["aMap"]["a"] = fA # Calcluate the area. dArea = misc.calc_area(dNew_port["aMap"]["a"], dNew_port["aMap"]["fScale"]) if dArea == None: return None # Compensate for inconsistency dArea_2 = {"val": dArea["qty"], "uom": dArea["uom"]} dNew_port["aArea"] = dArea_2 # End of map location entry # NAME IT! bExit = False while bExit == False: sMenu = "\nDo you want a to use host's name/a random name?" sRand_name_yn = misc.get_binary(sMenu) if sRand_name_yn == None: return None sName_only_lat = "" sName_only_cyr = "" # Manual entry: if sRand_name_yn == "N": print("\nPlease enter the name of the station / port in" + "(Use international Keyboard)") sName_only_lat = input() # User entered name in Cyrillic print("\nНапиш име стацйи люб порту в Цырполюю. " + "(пшэлаьч клавятурэ рэьчне)") sName_only_cyr = input() # Randomly generated Name elif sRand_name_yn == "Y": # Operated by an external routine import modules.x_random_names as rnd_name # We are storing the random names from the various systems here. # Hence, we will build up one set of arrays for the user to #choose aLat = [] aCyr = [] # Host name aLat.append(aHost_name["lat"]) aCyr.append(aHost_name["cyr"]) # Male-static: iNo_of_combos = 3 aName = rnd_name.rnd_male_name(iNo_of_combos) aSurname = rnd_name.qRnd_static_surname(iNo_of_combos) for iIdx in range(iNo_of_combos): sName = aName[iIdx]["lat"] sSurname = aSurname[iIdx]["lat"] aLat.append("{0} {1}".format(sName, sSurname)) sName = aName[iIdx]["cyr"] sSurname = aSurname[iIdx]["cyr"] aCyr.append("{0} {1}".format(sName, sSurname)) # Male-dynamic: iNo_of_combos = 3 aName = rnd_name.rnd_male_name(iNo_of_combos) aSurname = rnd_name.qRnd_dynamic_surname(iNo_of_combos) for iIdx in range(iNo_of_combos): sName = aName[iIdx]["lat"] sSurname = aSurname[iIdx]["lat"] aLat.append("{0} {1}".format(sName, sSurname)) sName = aName[iIdx]["cyr"] sSurname = aSurname[iIdx]["cyr"] aCyr.append("{0} {1}".format(sName, sSurname)) # Female-static: iNo_of_combos = 3 aName = rnd_name.rnd_female_name(iNo_of_combos) aSurname = rnd_name.qRnd_static_surname(iNo_of_combos) for iIdx in range(iNo_of_combos): sName = aName[iIdx]["lat"] sSurname = aSurname[iIdx]["lat"] aLat.append("{0} {1}".format(sName, sSurname)) sName = aName[iIdx]["cyr"] sSurname = aSurname[iIdx]["cyr"] aCyr.append("{0} {1}".format(sName, sSurname)) # Female-dynamic: iNo_of_combos = 3 aName = rnd_name.rnd_female_name(iNo_of_combos) aSurname = rnd_name.qRnd_dynamic_surname(iNo_of_combos) for iIdx in range(iNo_of_combos): sName = aName[iIdx]["lat"] sSurname = aSurname[iIdx]["lat"] aLat.append("{0} {1}".format(sName, sSurname)) sName = aName[iIdx]["cyr"] sSurname = aSurname[iIdx]["cyr"] aCyr.append("{0} {1}".format(sName, sSurname)) # Display the names iNo_of_names = len(aLat) sChoices = "0: Choose again\n" # Don't like the options iCnt = 1 for idx in range(0, iNo_of_names): sTxt = "{0}: {1} / {2}\n" sChoices += sTxt.format(iCnt, aLat[idx], aCyr[idx]) iCnt += 1 iChoice = misc.get_int(sChoices, iNo_of_names) if iChoice == None: return None # Invalid choice if iChoice == 0: continue # Choose again. iChoice -= 1 # Export the final names sName_only_lat = aLat[iChoice] sName_only_cyr = aCyr[iChoice] # Prepare post-fix sLat_Intl = "" sCyr_Intl = "" if dNew_port["level"] == "Int'l": sLat_Intl = "International" # The joys of Slavic grammar! if dNew_port["type"] in ["Rail"]: sCyr_Intl = "Меьдзыщнародова" elif dNew_port["type"] in ["Water", "Road"]: sCyr_Intl = "Меьдзыщнародовы" elif dNew_port["type"] in ["Air"]: sCyr_Intl = "Меьдзыщнародовэ" # Type of transport sLat_B = "" sCyr_B = "" # Rail #################################################### if dNew_port["type"] == "Rail": if dNew_port["sub_type"] == "Pax": sLat_B = "Train Station" sCyr_B = "Стаця Колеёва" elif dNew_port["sub_type"] == "Freight": sLat_B = "Freight Station" sCyr_B = "Стаця Товарова" elif dNew_port["sub_type"] == "Livestock": sLat_B = "Livestock Station" sCyr_B = "Стаця Звъежаьт" # Road - - - - - - - - - - - - - - - - - - - - - - - - - - - elif dNew_port["type"] == "Road": if dNew_port["sub_type"] == "Pax": sLat_B = "Bus Station" sCyr_B = "Двожэс Алтобусовы" elif dNew_port["sub_type"] == "Freight": sLat_B = "Truck Depot" sCyr_B = "Двожэс Товаровы" elif dNew_port["sub_type"] == "Livestock": sLat_B = "Livestock Depo" sCyr_B = "Двожэс Звъежэьтьи" # Water ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ elif dNew_port["type"] == "Water": if dNew_port["sub_type"] == "Pax": sLat_B = "Passanger Harbour" sCyr_B = "Порт Особовы" elif dNew_port["sub_type"] == "Freight": sLat_B = "Freight Harbour" sCyr_B = "Порт Товаровы" elif dNew_port["sub_type"] == "Livestock": sLat_B = "Livestock Harbour" sCyr_B = "Порт Звъежэьтьи" # Air > > > - - - - - - - - - - - - - - - - - < < < elif dNew_port["type"] == "Air": if dNew_port["sub_type"] == "Pax": sLat_B = "Airport" sCyr_B = "Лётниско" elif dNew_port["sub_type"] == "Freight": sLat_B = "Freight Airport" sCyr_B = "Лётниско Товаровэ" elif dNew_port["sub_type"] == "Livestock": sLat_B = "Livestock Airport" sCyr_B = "Лётниско Звъежэьцэ" else: print("Invalid choice. Exiting") return None # Full Latin name if sLat_Intl == "": sTxt = "{0} {1}".format(sName_only_lat, sLat_B) else: sTxt = "{0} {1} {2}".format(sName_only_lat, sLat_Intl, sLat_B) dNew_port["aName"]["lat"] = sTxt # Cyrillc grammar if sCyr_Intl == "": sTxt = "{1} о им. {0}".format(sName_only_cyr, sCyr_B) else: sTxt = "{1} {2} о им. {0}" sTxt = sTxt.format(sName_only_cyr, sCyr_Intl, sCyr_B) dNew_port["aName"]["cyr"] = sTxt # Confirm the name choice sNew_lat = dNew_port["aName"]["lat"] sNew_cyr = dNew_port["aName"]["cyr"] sMenu = "Are the names:\n'{0}'\n'{1}' OK?" sMenu = sMenu.format(sNew_lat, sNew_cyr) sNames_ok_yn = misc.get_binary(sMenu) if sNames_ok_yn == "Y": bExit = True # End of 'its named' # SERVICES: WHICH AREA DOES THIS FACILITY SERVICE bDone = False # Multiple areas. while bDone == False: sTxt = ( "\nThis station/port serves the people of ___." + "\n(Enter the geo-code of the entity OR Press '.' to exit loop") print(sTxt) sGeo_code = input().upper() if sGeo_code in ["", None, "."]: bDone = True continue # Verify the geo-code aName = misc.verify_geo_code(sGeo_code, cDest) if aName == None: bDone = True continue # Geocode verified, add the geo code to the list dNew_port["lServices"].append(sGeo_code) sLat_name = aName["lat"] sCyr_name = aName["cyr"] print("({0} / {1})".format(sLat_name, sCyr_name)) # end of while loop # WAREHOUSE: lSta_Whs = dNew_port["lWarehouse"] # Station warehouse for sTown in dNew_port["lServices"]: # Passanger or freight? if dNew_port["sub_type"] == "Pax": aData = {} # Travel demand: Why not model on Newton's equation of gravitation: # F = G*m1*m2 / r^2. Where, 'm' would be the population. xParam = {"geo_code": sTown} xRestr = {"_id": 0, "aDemographics": 1} dRun_query = cDest.find(xParam, xRestr) for query in dRun_query: aData = query["aDemographics"] # Freight or livestock: else: # Pull the data from the warehouses. dClt_whs = [] # List, client warehouse xParam = {"geo_code": sTown} xRestr = {"_id": 0, "aWarehouse": 1} dRun_query = cDest.find(xParam, xRestr) for query in dRun_query: dClt_whs = query["aWarehouse"] # The could be no data in the warehouse if dClt_whs == {}: continue # Extract the data from the warehouse for sShelf in dClt_whs: # Pull the data apart: look what is on the 'shelf' dContent = dClt_whs[sShelf] sResource = dContent["resource"].lower() fAmount = dContent["annual_output"] xUnits = dContent["units"] if xUnits == "t/yr": xUnits = "t/wk" elif xUnits == "kg/yr": xUnits = "kg/wk" elif xUnits == "kt/yr": xUnits = "kt/wk" else: print("Units are not presented as weight per year") # We have "shelves" in the warehouse already bNot_found = True for dSta_whs_shelf in lSta_Whs: # Find the correct shelf to add the contents. if dSta_whs_shelf["resource"] != sResource: continue if dSta_whs_shelf["units"] != xUnits: print("\n\aUnits mismatch at the warehouse. EXITING") return None fWeekly_produce = round(fAmount / 52, 2) fWeekly_total = dSta_whs_shelf["weekly_output"] fSub_tot = round(fWeekly_total + fWeekly_produce, 2) dSta_whs_shelf["weekly_output"] = fSub_tot bNot_found = False # We need to add another shelf to the warehouse: if bNot_found == True: dEntry = {} dEntry["resource"] = sResource # NOTE: Logistics run on weekly cycles. dEntry["weekly_output"] = round(fAmount / 52, 2) dEntry["units"] = xUnits lSta_Whs.append(dEntry) # End of warehouse shelf created # end of going through each of the client's shelves # end of freight/livestock vs passangers # end of going through the towns on the include list. fTot_weight = 0.0 for dEntry in dNew_port["lWarehouse"]: sName = dEntry["resource"] fAmount = dEntry["weekly_output"] sUnits = dEntry["units"] if sUnits == "t/wk": fTot_weight += fAmount # Publish total weight elif sUnits == "kt/wk": fTot_weight += fAmount * 1000 elif sUnits == "kg/wk": fTot_weight += fAmount / 1000 sTxt = "{0}: {1}{2}".format(sName, fAmount, sUnits) print(sTxt) if len(dNew_port["lWarehouse"]) > 0: fTot_weight = round(fTot_weight, 3) # Round off . fTot_daily = fTot_weight / 5.0 # MON to FRI fTot_daily = round(fTot_daily, 3) sTxt = "-------------\n" sTxt += "TOTAL: {0}t/wk\n".format(fTot_weight) sTxt += "TOTAL: {0}t/day\n".format(fTot_daily) print(sTxt) # Number of loading bays sTxt = ("\nEnter the number of 'loading zones'. " + "Take into account the imports") iLoading_zones = misc.get_int(sTxt) if iLoading_zones == None: return dNew_port["iLoading_zones"] = iLoading_zones # ATTACH TO HOST if dNew_port["type"] == "Rail": if dNew_port["sub_type"] == "Pax": sInd_code = "QP1" # Passanger operations else: # Freight / livestock operations sInd_code = "QF1" # ROAD TRANSPORT elif dNew_port["type"] == "Road": if dNew_port["sub_type"] == "Pax": sInd_code = "QB1" # Bus operations else: sInd_code = "QT1" # Truck port. Currently at 20t / trip # Air TRANSPORT elif dNew_port["type"] == "Air": if dNew_port["sub_type"] == "Pax": sInd_code = "QA1" # Passanger air ops else: sInd_code = "QG1" # Freight air ops dBriefcase = { "ccTremb": ccTremb, # Link to all the databases "sGeo_code": dNew_port["host_geo_code"], # of the host "sInd_code": sInd_code, # Passanger or Freight? "sName_lat": dNew_port["aName"]["lat"], # Don't overkill it. "sYour_id": dNew_port["my_id"], # When constructed in city, link it! "aArea": dNew_port["aArea"], # Footprint "iNo_of_builds": 1, # Number of stations. "lServices": dNew_port["lServices"], # Who makes use of this? "fCapacity": None, # How much is used (schools, ect) } xFeedback = d_py.add_wkp_auto(dBriefcase) if xFeedback == None: return cStation.insert_one(dNew_port) print("\n>>>\nNew station added")
def view_child_demands(ccTremb): """ Draws up a table showing the children and their demand for police stations, clinics, ect """ # Get the parent's geo-code sMenu = "\nEnter the geo-code of the parent (ex. VAA-00)" print(sMenu) sParent = input().upper() # Get the parent cDest = db.destinations(ccTremb) # Get the database dParent = misc.get_geo_element(sParent, cDest) if dParent == None: return None # Open a text file where a copy of the information will be written to. if sParent == "*": sFile_name = "world" # Exception in naming convention else: sFile_name = sParent # Work out a name of the file sFile_path = "Logs/a_{0}_child_demands.txt".format(sFile_name) eChild_data = open(sFile_path, "w", encoding="utf-8") sHeading = "Children and their service demands\n" eChild_data.write(sHeading) # Get the unit capacities: cCity_services = db.city_services_const(ccTremb) xParam = {} xRestr = {"_id": 0} dCity_query = cCity_services.find(xParam, xRestr) # Copy out the query aCity_copy = [] for dItem in dCity_query: aCity_copy.append(dItem) sSubtitle = "{:>32.32} :".format("Service code") sBreak = "{:>32.32} :".format("-" * 32) for dService in aCity_copy: sSubtitle += " {:^6.6}:".format(dService["code"]) sBreak += "-" * 7 + ":" # Creates a visual break eChild_data.write(sSubtitle + "\n") eChild_data.write(sBreak + "\n") # LOOP THROUGH EACH CHILD for child in dParent["aChildren"]: # Query each child on their identifier xParam = {"my_id": child} xRestr = {"_id": 0} dChild_query = cDest.find(xParam, xRestr) # Go through every child' details for dThe_child in dChild_query: # The query is an array. # Get the names out sChd_id = dThe_child["geo_code"] sChd_lat = dThe_child["aName"]["lat"] sChd_cyr = dThe_child["aName"]["cyr"] sLine = "{0:>7.7}: {1:>10.10} / {2:<10.10} :" # <Justfy>Length.precision sLine = sLine.format(sChd_id, sChd_lat, sChd_cyr) # Start looping through the services aDgfx = dThe_child["aDemographics"] # Go through each of the services: for dService in aCity_copy: if aDgfx == {}: # No data for demographics sLine += " {0:^6.6}:".format("N/A") continue # Alternative to 'else' sServes = dService["serves"] # Population group concerned iCapacity = dService["capacity"] # Customers per unit fUnits_reqd = aDgfx[sServes] / iCapacity # Calculate! sLine += " {0:6.2f}:".format(fUnits_reqd) # "|123.45" sLine += "\n" eChild_data.write(sLine) # End of going through each child in the query # End of going through each child in the parent eChild_data.write(sBreak + "\n") eChild_data.write(sSubtitle + "\n") eChild_data.close()
def add_community_services(ccTremb): """ Adds the the following items to the database. It takes data from the map. The actual number of employees will be determined later. These can be placed first; its service region can be edited later. Another method will update these and their hosts. The list of items accessed through here is: 5YP: Community Police station, 5YF: Community Fire station, 5YH: Community clinics, 5YG: Community governance, ED0: Pre-school, ED1: Primary School, ED2: Middle School, ED3: High School, OAH: Standard Old Age Home, 5SŠ: Community shop ("Small Šop"), 5LX: Community Libraries, 5TH: Community Theatres, 5PO: Community Post Offices. """ # Obtain the highest "my_id" code that is registered in the database. xParam = {} xRestr = {"_id": 0, "my_id": 1} cCommunity = db.community_services(ccTremb) dId_query = cCommunity.find(xParam, xRestr) iHighest, aEvery_id = misc.find_highest_id(dId_query) # We do have the highest identifier (expressed as a decimal number). Hence, # we can incerement the sequence and use it. iNext_id = iHighest + 1 if iNext_id > 36**5: print("\n\aMaximum count has been exceeded") return None # Convert to base36 sBase36 = misc.base_conv(iNext_id) sBase36_5 = sBase36.rjust(5, "0") # "0002W" -> "D00-02W" sNew_id = "A{0}-{1}".format(sBase36_5[:2], sBase36_5[2:]) print("\nNext id is {0}".format(sNew_id)) # START GETTING THE USER TO ENTER THE NEW DATA. # Open a blank dictionary, so that the elements are arranged in a certain # order. dNew_service = { "my_id": sNew_id, "host_geo_code": None, "aName": { "lat": None, "cyr": None }, # Is the block of flats named? "type_code": None, # "5YP" for example "type_name": "", # "Police" "iNo_of_units": 1, # Multiple units operating from one site. "sub_type": None, # RFU "aServes": [], # Geo-codes of commuinties it serves. "iClients": 0, # Quick summary of clients supplied "iCapacity": 0, # Summary of how much we can hold "sNotes": "", # Irregular building "aMap": { "sRegion": None, "iYear": None, "fScale": None, "x": None, "y": None, "a": None }, "aFtp_bldg": { "qty": None, "uom": None }, "aArea_plot": { "qty": None, "uom": None }, } # HOST cDest = db.destinations(ccTremb) # To verify the geocode sTxt = ("\nWho is hosting this community service?" + " Please enter thier geo-code.") print(sTxt) sGeo_code = input().upper() dHost_element = misc.get_geo_element(sGeo_code, cDest) if dHost_element == None: return dNew_service["host_geo_code"] = sGeo_code aHost_name = dHost_element["aName"] sTxt = "\nHosted by {0} / {1}".format(aHost_name["lat"], aHost_name["cyr"]) print(sTxt) # MAKE A LIST OF THE SERVICES cCity_services = db.city_services_const(ccTremb) xParam = {} xRestr = {"_id": 0} dCity_query = cCity_services.find(xParam, xRestr) # Copy out the query dCity_copy = [] for dItem in dCity_query: dCity_copy.append(dItem) # Setup the menu sMenu = ("\nWhich service are you adding? (Invalid entry will exit)\n") iCnt = 0 for dOne_service in dCity_copy: iCnt += 1 sCode = dOne_service["code"] sName = dOne_service["name"] sMenu += ("{0}: [{1}] {2}\n".format(iCnt, sCode, sName)) # Print the menu and get the response iChoice = misc.get_int(sMenu, 13) if iChoice == None: return None # Select the service dSvc = dCity_copy[iChoice - 1] # Count started at one! # Record the code dNew_service["type_code"] = dSvc["code"] # 5YP for example dNew_service["type_name"] = dSvc["name"] # Police for example # MAP REFERENCE sMap = dSvc["name"] dData = misc.get_map_input(ccTremb, sMap) # Asks for user to input stuff. if dData in [None, True]: # No map selected print("\n\aInvalid entry from the map. Exiting") return None # Transfer data through. dNew_service["aMap"] = dData["dMap"] dNew_service["aArea_plot"] = dData["dArea"] # BUILDING: sTxt = "Is the size of the actual building(s) known?" sYn_bldg = misc.get_binary(sTxt) if sYn_bldg == None: return None if sYn_bldg == "Y": sTxt = "\nEnter the footprint of the building in sq.mm from map." fBldg_ftp = misc.get_float(sTxt) if fBldg_ftp == None: return None # Calculate area fScale = dNew_service["aMap"]["fScale"] dNew_service["aFpt_bldg"] = misc.calc_area(fBldg_ftp, fScale) # NAME THE FACILITY aName = misc.building_name() if aName == None: return None if aName != False: # A name was chosen dNew_service["aName"] = aName # Building count sTxt = ("How many units operate from this facility?") iNo_of_units = misc.get_int(sTxt) if iNo_of_units == None: return None dNew_service["iNo_of_units"] = iNo_of_units # Calculate total customer capacity: fTot_cust = iNo_of_units * dSvc["capacity"] iTot_cust = int(round(fTot_cust, 0)) # Just to be sure. dNew_service["iCapacity"] = iTot_cust # SERVICES: WHICH AREA DOES THIS FACILITY SERVICE # While here, show live updates of the service demand. sDgfx_code = dSvc["serves"] # iTOT-PAX for example bDone = False # Multiple areas. while bDone == False: sTxt = ( "\nThis facility serves the people of ___." + "\n(Enter the geo-code of the entity OR Press '.' to exit loop") print(sTxt) sGeo_code = input().upper() if sGeo_code in ["", None, "."]: bDone = True continue # Verify the geo-code dCust_element = misc.get_geo_element(sGeo_code, cDest) if dCust_element == None: bDone = True continue # Geocode verified, add the geo code to the list dNew_service["aServes"].append(sGeo_code) sLat_name = dCust_element["aName"]["lat"] sCyr_name = dCust_element["aName"]["cyr"] # Sort out the capacity as we go along. sTxt = "{0} / {1}:\n".format(sLat_name, sCyr_name) sTxt += "{0} is ".format(sDgfx_code) aDgfx = dCust_element["aDemographics"] # Shorter access if aDgfx == {}: dNew_service["sNotes"] += " {0}*,".format(sGeo_code) sTxt += ("N/A") else: iClients = aDgfx[sDgfx_code] sTxt += ("{0}\n".format(iClients)) dNew_service["iClients"] += iClients iNs_clt = dNew_service["iClients"] iNs_cap = dNew_service["iCapacity"] fPercentage = iNs_clt / iNs_cap sPercentage = "{:.3f}".format(fPercentage) # Hopefully "0.344" sTxt_a = ("Total clients: {0} / {2} = ({1} of capacity)") sTxt += sTxt_a.format(iNs_clt, sPercentage, iNs_cap) print(sTxt) # end of while loop, servicing the facilities. print("Enter comments (if any)") dNew_service["sNotes"] += "| " dNew_service["sNotes"] += input() # UPDATE THE WORKPLACE SUPPLY. # Create the element first. It will either be overridden or a new entry will # be created fDenominator = dNew_service["iCapacity"] * iNo_of_units if fDenominator == 0.00: print("\n\aDivide by zero error caught during capacity calc. Exiting") return None fNumerator = dNew_service["iClients"] fCapacity = fNumerator / fDenominator sCapacity = "{:.3}".format(fCapacity) dThe_item = { "iCnt": iNo_of_units, # How many pre-schools in this facility "sCode": dSvc["code"], # 5YH for example "sName": dNew_service["my_id"], # A00-001 for example (unique) "lServices": dNew_service["aServes"], # Geo-codes within the scope "fCapacity": sCapacity, # Needs to be calculated } print(dThe_item) # for aDemand_workforce print(dNew_service) # Own database entry # WRITE TO DATABASE aSupply_workplace = dGeo_element["aSupply_workplace"] aSupply_workplace.append(dThe_item) xParam = {"geo_code": dNew_service["host_geo_code"]} xNew_data = { "$set": { "aSupply_workplace": aSupply_workplace, } } cDest.update_one(xParam, xNew_data) cCommunity.insert_one(dNew_service) print(">>> Databases updated ({0})".format(dNew_service["my_id"]))
def qEvent_station(dPack): """ This function builds up a piece of station for us. dPack = { "tremb": ccTremb, # For full DB access. "db": cLine, # Database entries for the line. "dEntry": { # This parameter will be passed back "km":fDist, # kmilage marker "id":iHighest+1, # Unique reference number "item":None, # We need to fill this with our data "type":None, # We need to fill this with our data "xVal":None}, # We need to fill this with our data } """ dEntry = dPack["dEntry"] # Unpack the prototype sMenu = ("Please select the station event from the list") sMenu += "Select track event:\n" sMenu += "0 Comment (record something unusual)\n" sMenu += "1 Registered host: (geo_code is known)\n" sMenu += "2 Approximate host: (geo_code not verified)\n" print(sMenu) sInput = input().upper() # COMMENT if sInput == "0": # Comment dEntry["item"] = "station" dEntry["type"] = "comment" # Type of transaction sTxt = "Please enter a comment regarding station" print(sTxt) dEntry["xVal"] = input() return dEntry # REGISTERED HOST if sInput == "1": #"dEntry":{"km":fDist,"id":0,"item":None,"type":None,"xVal":None}, dEntry["item"] = "station" dEntry["type"] = "geo_code" # Type of transaction sTxt = "Please enter the geo_code of the station's host:" print(sTxt) sGeo_code = input().upper() # Verify existance of this geo-code cDest = db.destinations(dPack["tremb"]) # Wrapper for 'ccTremb' aName = misc.verify_geo_code(sGeo_code, cDest) if aName == None: return None # verification failed xVal = {"geo": sGeo_code, "lat": aName["lat"], "cyr": aName["cyr"]} dEntry["xVal"] = xVal return dEntry # APPROXIMATE HOST if sInput == "2": #"dEntry":{"km":fDist,"id":0,"item":None,"type":None,"xVal":None}, dEntry["item"] = "station" dEntry["type"] = "approx" # Type of transaction sTxt = ( "Please enter the APPROXIMATE geo_code of the station's host:" + " \n'? are allowed, code will not be verified") print(sTxt) sApprox_code = input().upper() sTxt = ("Please enter a description, if available") sDesc = input() xVal = { "code": sApprox_code, "desc": sDesc, } dEntry["xVal"] = xVal return dEntry else: print("\n\aInvalid selection. Exiting") return None
def add_line(ccTremb): """ Creates a new railway line meta-data header in the database. Use the 'append' function to add the details to it. However, those details will be dataase entries themselves. This is the classic debate, few large documents vs lots of small documents.""" # Obtain the highest "my_id" code already registered. # Get a list of all the registered base-36 codes xParam = {} xRestr = {"_id": 0, "my_id": 1} cLine = db.lines(ccTremb) dId_query = cLine.find(xParam, xRestr) iHighest, aEvery_id = misc.find_highest_id(dId_query) if (True): # Debugging sTxt = "\n\nHighest number is {0}(10) < < < < < < < <" print(sTxt.format(iHighest)) # We do have the highest identifier (expressed as a decimal number). Hence, # we can incerement the sequence and use it. iNext_id = iHighest + 1 if iNext_id > 36**5: print("\n\aMaximum count has been exceeded") return None # Convert to base36 sBase36 = misc.base_conv(iNext_id) sBase36_5 = sBase36.rjust(5, "0") # "0002W" -> "D00-02W" sNew_id = "K{0}-{1}".format(sBase36_5[:2], sBase36_5[2:]) # Display the number print("\nCode assigned will be: '{0}'".format(sNew_id)) # PREPARE THE TEMPLATE # Open a blank dictionary. I need to arrange the elements in order dNew_line = { "my_id": sNew_id, # K00-001 "tag": "meta", # Describes that this is the description "dVal": { "host_geo_code": None, # VA "route_no": None, # RFU for road B96 "sRoute_name": "", # "Vænesston-Kændis Beach (VA-FS)" "type": None, # RFU "start": None, # Where is the zero km count "end": None, # Where is the maximum point } # Closes "dVal" for the meta data } # GET THE HOST: sTxt = ( "\n\nPlease note that an unregistered host may be entered. Fill " + "out the known part\nof the geocode. Enter '?' as the final " + "character. Geocode will not be verified.\nIt will be entered as " + "'Unnamed'" + "\n\nPlease enter the geo-code of the Host:") print(sTxt) sGeo_code = input().upper() # Confirm host exists if sGeo_code[-1] != "?": cDest = db.destinations(ccTremb) aHost_name = misc.verify_geo_code(sGeo_code, cDest) if aHost_name == None: print("\n\aUnrecognised host name. Exiting") return sTxt = "\nHosted by {0} / {1}" print(sTxt.format(aHost_name["lat"], aHost_name["cyr"])) # Save the geocode dNew_line["dVal"]["host_geo_code"] = sGeo_code # ROUTE NUMBER sTxt = "Is the route number (Б96 for example) known?" yn_route = misc.get_binary(sTxt) if yn_route == "Y": sTxt = "\nPlease enter the route number:" dNew_line["dVal"]["route_no"] = input().upper() else: dNew_line["dVal"]["route_no"] = None # NAME OF THE STRETCH sTxt = ("\nPlease enter the name of this stretch. For example:\n" + "Vænesston-Kændis Beach (VA-FS)") print(sTxt) dNew_line["dVal"]["sRoute_name"] = input() # TODO: TYPE OF LINE # STARTING POINT sTxt = "\nIs the STARTING point known?" yn_start = misc.get_binary(sTxt) if yn_start == "Y": sTxt = ("\nWhere is the starting point? (Ex: 'VAA-00', " + "'[email protected]')") print(sTxt) dNew_line["dVal"]["start"] = input() else: print("TODO 'AXUZI'") return None # FINISHING POINT sTxt = "\nIs the ENDING point known?" yn_end = misc.get_binary(sTxt) if yn_end == "Y": sTxt = ("\nWhere is the ending point? (Ex: 'FS0', '[email protected]')") print(sTxt) dNew_line["dVal"]["start"] = input() else: print("TODO 'BZHAK'") return None # Meta data captured: cLine.insert_one(dNew_line) print(">>>\nNew line OPENED")