trailblazer | The advanced business logic framework for Ruby | Rule Engine library
kandi X-RAY | trailblazer Summary
Support
Quality
Security
License
Reuse
Currently covering the most popular Java, JavaScript and Python libraries. See a Sample Here
trailblazer Key Features
trailblazer Examples and Code Snippets
Trending Discussions on trailblazer
Trending Discussions on trailblazer
QUESTION
I am new to angular js and I would like to sort my array of events by date. Newer events first then older. I have a separate array file for the events.
Here is my array file, newsList.ts
export const newsList = [
{
title:'FilPass Holds Talk on Construction new Technology',
author: {
name: 'Hazel Chua',
date: 'June 3, 2021',
},
readTime: 7,
innerHTML: `
FilPass Tamperproof Tech Inc. launched on July 23 the Industry-Academe Linkage for Construction Series in pursuit of introducing its flagship project, the Construction Industry One Registry System or CIORS, to the Philippine construction industry, academe, and non-profit organizations.
As part of the 4-part series, FilPass will be holding a panel discussion titled, “Industry Academe Linkage for Construction Series: How the Construction Industry Adapts to New Technologies”, taking place on August 18, 2021, from 10:00 A.M. to 11:30 A.M. via AirMeet and streamed live on FilPass’ Facebook page.
The event will also serve as a mass memorandum of agreement signing for FilPass’ CIORS ambassadors, partners from the construction industry and academe, different partner merchants, and media partners.
It will be graced by esteemed trailblazers of the Philippine construction industry namely Engr. Jomel Molabola of Engineering Wins PH, Engr. Ralp Rivas of @itsaralp, Civil Engr. Samuel Pacba of the Technological University of the Philippines, and Gaze Kasilag-Del Castillo, Chair and President of FilPass.
The event will also serve as a mass memorandum of agreement signing for FilPass’ CIORS ambassadors, partners from the construction industry and academe, different partner merchants, and media partners.
Adding to that, FilPass ID holders, particularly CIORS signees, will get to enjoy exciting discounts and vouchers from five and counting partner merchants to be presented on the event. Meanwhile, a raffle contest is currently happening over FilPass’ Facebook page where different cash prizes await three special winners.
If you are a student, worker, and professional related in the field of construction, you may still register for the event by heading over to this link: https://rfr.bz/f36c40p
Watch out for more virtual events FilPass has in store for you! Follow FilPass on their social media pages Facebook and Instagram to stay updated.
`,
postLink: ['/news-article', 'FilPass Holds Talk on Construction new Technology'.toLowerCase().split(' ').join('-')],
paramLink: 'FilPass Holds Talk on Construction new Technology'.toLowerCase().split(' ').join('-'),
thumbnail: '../../../../assets/img/cropBlog4.jpg'
},
This is my JS file where I will put the sortEvents() function:
import { Component, OnInit } from '@angular/core';
import { newsList } from 'src/app/constants/newsList';
@Component(
{
selector: 'app-all-news-page',
templateUrl: './all-news-page.component.html',
styleUrls: ['./all-news-page.component.scss']
})
export class AllNewsPageComponent implements OnInit {
newsList:any;
constructor() { }
ngOnInit(): void {
this.newsList = newsList;
}
sortDate() {
//INSERT CODE HERE
}}
This is my HTML file:
ANSWER
Answered 2022-Apr-04 at 04:50Override sort function, parse Date and compare it
this.newsList.sort((a,b)=>{
const dt1 = Date.parse(a.author.date);
const dt2 = Date.parse(b.author.date);
if (dt1 < dt2) return 1;
if (dt1 > dt2) return -1;
return 0;
});
QUESTION
I have an object of NBA Team names structured like so:
const HomeAndAwayTeams =
{
teams: {
'0': { hTeam: 'San Antonio', AwTeam: 'New Orleans' },
'2': { hTeam: 'Sacramento', AwTeam: 'Orlando'
},
'4': { hTeam: 'Indiana', AwTeam: 'Toronto' },
'6': { hTeam: 'Chicago', AwTeam: 'Cleveland' },
'8': { hTeam: 'Brooklyn', AwTeam: 'Miami' },
'10': { hTeam: 'Milwaukee', AwTeam: 'Memphis'
},
'12': { hTeam: 'Oklahoma City', AwTeam: 'Denver' },
'14': { hTeam: 'Houston', AwTeam: 'Portland' } }
}
I'm looking to replace the City Names with their respective Team Nicknames.
I have an object setup that has their nicknames as the values, and the city names as the keys.
const NBATeamsNickNames = {
"Atlanta": "Hawks",
"Boston": "Celtics",
"Brooklyn": "Nets",
"Charlotte": "Hornets",
"Chicago": "Bulls",
"Cleveland": "Cavaliers",
"Dallas": "Mavericks",
"Denver": "Nuggets",
"Detroit": "Pistons",
"Golden State": "Warriors",
"Houston": "Rockets",
"Indiana": "Pacers",
"LA": "Clippers",
"Los Angeles": "Lakers",
"Memphis": "Grizzlies",
"Miami": "Heat",
"Milwaukee": "Bucks",
"Minnesota": "Timberwolves",
"New Orleans": "Pelicans",
"New York": "Knicks",
"Oklahoma City": "Thunder",
"Orlando": "Magic",
"Philadelphia": "76ers",
"Phoenix": "Suns",
"Portland": "Trailblazers",
"Sacramento": "Kings",
"San Antonio": "Spurs",
"Toronto": "Raptors",
"Utah": "Jazz",
"Washington": "Wizards"
}
I've tried several ways to replace the values, but I can't figure out how to access it if it was nested.
For example, I've tried something like this:
for (const key in NBATeamsNickNames) if (key in HomeAndAwayTeams) HomeAndAwayTeams = NBATeamsNickNames[key];
Which of course, only works if the object values in HomeAndAwayTeams weren't nested, and at base level.
I've attempted some other methods like a for loop, and a map, but I'm inexperienced in iterating over objects, especially in this format, and I'm trying to understand the concept behind accessing data in this way and replacing it in this case.
The number of teams in the HomeAndAwayTeams will change every day, it won't be a static amount. And of course, the teams within the object will change every day as well.
I appreciate any help, thank you.
ANSWER
Answered 2022-Mar-26 at 18:27I guess you don't need to iterate over HomeAndAwayTeams
object, you need to iterate over HomeAndAwayTeams.teams
. You can use Object.keys method to do it.
This will change your object in place.
const { teams } = HomeAndAwayTeams
for (const key of Object.keys(teams)) {
if (teams[key].hTeam in NBATeamsNickNames) {
teams[key].hTeam = NBATeamsNickNames[teams[key].hTeam]
}
if (teams[key].AwTeam in NBATeamsNickNames) {
teams[key].AwTeam = NBATeamsNickNames[teams[key].AwTeam]
}
}
QUESTION
I have two lists that I am trying to zip. I would like to zip them so that they match by their id
value. So, for row, the id would be 'Video ID'
and for founded_evideo, the id would be 'post_id'
. I would like to zip so that the ids match.
I have tried sorting the panda frame first using sort_values
function, but this doesn't seem to have an effect on the zip function. Ex:
Code
founded_edvideos_list = find_matching_posts_forupdate(video_id_list, stop_at_page=stop_at_page)
founded_edvideos_df = pd.DataFrame(founded_edvideos_list)
founded_edvideos_df = founded_edvideos_df.sort_values(by=['post_id'], ascending=True)
founded_edvideos_df = founded_edvideos_df.where(pd.notnull(founded_edvideos_df), None)
excel_data = file_as_df[file_as_df['Video ID'].isin(founded_edvideos_df['post_id'])]
excel_data = excel_data.copy()
excel_data['Video ID'] = excel_data['Video ID'].astype("category")
excel_data['Video ID'].cat.set_categories(file_as_df['Video ID'].to_list(), inplace=True)
excel_data.sort_values(["Video ID"])
excel_data = excel_data.to_dict('r')
for (row,founded_evideo) in zip(excel_data,founded_edvideos_list):
more code
row example
{
'Video ID': 12894,
'Title': 'Trailblazer Melba Pattillo Beals',
'Excerpt': 'Meet Melba Pattillo Beals PhD., member of the Little Rock Nine, and trailblazer for civil rights.',
'Video Description': 'Meet Melba Pattillo Beals PhD., member of the Little Rock Nine, and trailblazer for civil rights.',
'Quick Ideas for Using the Video': '',
'Video URL': 'https://vimeo.com/32351',
'Keywords': "African American History, African American Studies, America and Civil Rights"
}
founded_evideo example
{
'post_id': 12994,
'title': 'Trailblazer Melba Pattillo Beals',
'video_page_description': 'Meet Melba Pattillo Beals PhD., member of the Little Rock Nine, and trailblazer for civil rights.',
'content': 'Meet Melba Pattillo Beals PhD., member of the Little Rock Nine, and trailblazer for civil rights.
\n',
'quick_ideas': '',
'video_url': 'https://vimeo.com/3242',
'keywords': ''
}
ANSWER
Answered 2022-Mar-05 at 20:06You could try like this:
l1 = [
{"Video ID": 12894, "Title": "title1"},
{"Video ID": 14897, "Title": "title2"},
{"Video ID": 45124, "Title": "title4"},
{"Video ID": 54613, "Title": "title3"},
]
l2 = [
{"post_id": 54613, "Title": "title3"},
{"post_id": 10278, "Title": "title4"},
{"post_id": 12894, "Title": "title1"},
{"post_id": 14897, "Title": "title2"},
]
common_ids = set(item["post_id"] for item in l2).intersection(
set(item["Video ID"] for item in l1)
)
def new(list, key):
"""Helper function which returns list of dicts which ids are found in common_ids."""
return sorted(
[item for item in list if item[key] in common_ids], key=lambda x: x[key]
)
for item1, item2 in zip(new(l1, "Video ID"), new(l2, "post_id")):
print(item1, item2)
# Output
{'Video ID': 12894, 'Title': 'title1'} {'post_id': 12894, 'Title': 'title1'}
{'Video ID': 14897, 'Title': 'title2'} {'post_id': 14897, 'Title': 'title2'}
{'Video ID': 54613, 'Title': 'title3'} {'post_id': 54613, 'Title': 'title3'}
QUESTION
I am using Panda version is 1.3.5 and I am running into an error when I am trying to use the sort_values
function.
code
founded_edvideos_list = find_matching_posts_forupdate(video_id_list, stop_at_page=stop_at_page)
founded_edvideos_df = pd.DataFrame(founded_edvideos_list)
founded_edvideos_df = pd.sort_values(by=['post_id'], ascending=True)
The last line gives an error
getattr__ raise AttributeError(f"module 'pandas' has no attribute '{name}'") AttributeError: module 'pandas' has no attribute 'sort_values'
When I print the dataframe, it looks like the following, so I should be able to use the post_id
. I have checked the documentation and can't seem to find my issue.
dataframe
post_id title ... vid_type vid_record
0 12994 Trailblazer Melba Pattillo Beals ... [6923, 6926] [6929]
1 12992 Trailblazer Asha Prem ... [6923] [6929]
2 12894 Trailblazers Melisa Mujanovic and Nina Nukic ... [6923, 6926] [6929]
ANSWER
Answered 2022-Mar-01 at 18:37You're calling pandas.sort_values
instead of calling sort_values
on an instance of pandas.Dataframe
. Your sorting line should likely be:
founded_edvideos_df = founded_edvideos_df.sort_values(by=['post_id'], ascending=True)
QUESTION
In the code below, I call an NBA api, and create an array from a specific bracket within it. However, this only gives me an array full of numbers, which are the NBA team's ID's. I'm trying to change all of the values into the Team name's themselves and list them. For example, '29' would be the Portland Trailblazers; 25 would be the Oklahoma City Thunder.
I've tried multiple threads with similar problems, but have yet to find something that works.
Code:
var idarray = [];
var idz = response.api.standings
for (var i = 0; i < idz.length; i++) {
idarray.push(idz[i].teamId);
}
console.log(idarray)
Array that prints out from above code:
[
'41', '5', '20', '1', '26',
'24', '4', '27', '38', '2',
'6', '21', '7', '15', '10',
'19', '14', '8', '31', '23',
'11', '30', '28', '16', '17',
'40', '22', '9', '29', '25'
]
ANSWER
Answered 2021-Nov-19 at 10:481. First of all, you need to map all team ID's to their names, something like this:
// key -> ID, value -> name
const teamNames = {
25: 'Oklahoma City Thunder',
29: 'Portland Trailblazers',
...
}
2. Then you can transform your array:
// For example idarray = [25, 29] initially
idarray = idarray.map(id => teamNames[id]);
console.log(idarray);
Output:
[ 'Oklahoma City Thunder', 'Portland Trailblazers' ]
Extra: mapped array is ready to print as standings list, for example:
for (let index in idarray) {
console.log(`${index + 1}. ${idarray[index]}`);
}
Output:
1. Oklahoma City Thunder
2. Portland Trailblazers
QUESTION
Update: to explain what type of Datatables I Am comparing- "Compare two Datatables with the same columns, one Datatable is being pulled form an external server and inserted Initially, from then onwards only last 6 months of records are pulled off external database (for various reasons) , and the data is compared with local data (for a 6 month date range) to see if a DataRow has changed,needs to be deleted or added where the Row Identifier (PKey)which is essentially the SalesID + LineRow match and other columns are values to be compared to see if that row needs to be re-added/deleted because incoming columns are different to current columns and also delete rows where the incoming data does not contain those rows
so basically I want a Exclusive Left Join [to insert that data] and Exclusive Right Join [to delete that data] "
I have been doing some database coding as well as JSON pulling and I want to know what is the standard way / correct way of doing things , I started with 2 hour compare times (on dummy DB table) down to 1 hour to 1 secs (after applying my janky method to DB table Compare) and then finally used it on live pull with what seems to be correct and consistent results and so I started doing testing on Dummy data with it going from 1 hour to 26 minutes to finally <1 seconds (using my own janky way), Table sizes tested and assumed are between 100,000 & 200,000 rows so lets go through the standard methods I tried and then go onto the janky solution I Made.
The first and obvious idea was to use two ForEach
iterations (even mentally this seemed it would be slow however I thought it wouldn't be that bad considering how quick Add is, and how quickly you can compare JSON Tokens when iterating through Jarrays). Code was something like the following:
DataTable dtQueryItemsDiff = dtItems.Clone();
DataTable dtItemsDiff = dtItems.Clone();
int maxRowCountCache = dtItems.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name")).Count();
int rowcountCCache = 0;
var query = dtQuery.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name"));
foreach (DataRow drDTI in dtItems.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name")))
{
int innerrowcount = 0;
bool rowfound = false;
if (query.Count() != 0)
{
foreach (DataRow drDTQ in query)
{
if (drDTI["SalesID"].ToString() == drDTI["SalesID"].ToString() && drDTI["LineNumber"].ToString() == drDTI["LineNumber"].ToString())
{
rowfound = true;
break;
}
innerrowcount++;
}
}
else
{
dtItemsDiff.ImportRow(drDTI);
continue;
}
if (rowfound == true)
{
orderedDtquery.ElementAt(innerrowcount).Delete();
}
else
{
dtItemsDiff.ImportRow(drDTI);
}
rowcountCCache++;
BeginInvoke(new MethodInvoker(delegate
{
lblDataLoadC.Text = rowcountCCache.ToString() + " / " + maxRowCountCache.ToString();
}));
}
if (query.Count() != 0)
{
foreach (DataRow drDTQ in query)
{
dtQueryItemsDiff.ImportRow(drDTQ);
}
}
This took quite a long time about an 1H (1 Hour) to 1.5H depending on data how it was ordered etc. The benefit was that I could granularly change the code and it gave me Non-matched data in both tables, also it reduced query size searched but this wasn't fast enough for me so then I tried Linq searching where I didn't reduce list size as a I went (it was slower to delete then search then it was to just search) and this took about ~40-50 mins and looked like:
int maxRowCountCache = dtItems.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name")).Count();
int rowcountCCache = 0;
dtItems.AcceptChanges();
foreach (DataRow drDTI in dtItems.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name")))
{
var checkIfRecordInIDB = progSettings.query.AsEnumerable().Where(row => row.Field("CardRecordID") == drDTI["CardRecordID"].ToString()
&& row.Field("Date") == drDTI["Date"].ToString() && row.Field("SaleID") == drDTI["SaleID"].ToString()
&& row.Field("ItemID") == drDTI["ItemID"].ToString() && row.Field("LineNumber") == Convert.ToInt64(drDTI["LineNumber"].ToString())).FirstOrDefault();
if (checkIfRecordInIDB != null)
{
drDTI.Delete();
}
rowcountCCache++;
BeginInvoke(new MethodInvoker(delegate
{
lblDataLoadC.Text = rowcountCCache.ToString() + " / " + maxRowCountCache.ToString();
}));
}
dtItems.AcceptChanges();
Benefit of this is its slightly more lazy, faster and concise, however it only gives you data in one table much like Except does and that is exactly what I tried next using ~100,000 rows of dummy data, this took 26 minutes and 35 seconds.
dtItems.Rows.Clear();
query.Rows.Clear();
Thread start = new Thread(timerAndUIupdate);
start.Start();
dtItems.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "72421ee8-459b-46fb-bf5a-f51e80976e5a", "Pioneer 1kg (FT), RRP $42", "100115", 1, 25.0, "N");
dtItems.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "8885a911-8d32-4dfe-93e5-2e453fd54db9", "Decaf Beans 250g FT", "1002302", 2, 2.0, "N");
dtItems.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "e3aa4b15-b774-4f6a-ac21-77fa05a4332f", "P&R Cups 06oz (1000)", "30056", 3, 1.0, "N");
dtItems.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "51e1a867-4079-4a3c-9ddc-e93d87d80b46", "P&R Cups 12oz (1000)", "30058", 4, 1.0, "N");
query.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "72421ee8-459b-46fb-bf5a-f51e80976e5a", "Pioneer 1kg (FT), RRP $42", "100115", 1, 25.0, "N");
query.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "8885a911-8d32-4dfe-93e5-2e453fd54db9", "Decaf Beans 250g FT", "1002302", 2, 2.0, "N");
query.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "e3aa4b15-b774-4f6a-ac21-77fa05a4332f", "P&R Cups 06oz (1000)", "30056", 3, 1.0, "N");
query.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "51e1a867-4079-4a3c-9ddc-e93d87d80b46", "P&R Cups 12oz (1000)", "30058", 4, 1.0, "N");
for (int i = 1; i < 100000; i++)
{
dtItems.Rows.Add("Bennett St Dairy", "ed0c8d30-6469-4e13-af5a-36d7357a4a70", "2019-07-01", "2019-07-01", "8b909a4b-a07b-4a06-bebc-6a3387433aaf", "c8cc1115-da02-42cf-b427-accc1b6d07e3", "Trailblazer 1Kg, RRP $44", "10011", i, (i * 4), "N");
query.Rows.Add("Bennett St Dairy", "ed0c8d30-6469-4e13-af5a-36d7357a4a70", "2019-07-01", "2019-07-01", "8b909a4b-a07b-4a06-bebc-6a3387433aaf", "c8cc1115-da02-42cf-b427-accc1b6d07e3", "Trailblazer 1Kg, RRP $44", "10011", i, (i * 4), "N");
}
dtItems.Rows.Add("Air Coffee International Cafe Pty Ltd", "bb4fa724-9759-4c60-93fe-70fbdfd00417", "2019-07-01", "2019-07-01", "b972f020-3740-4ef2-941f-78b1a9edefa8", "0be54733-ac0e-43f9-8ea5-204c7cdb5f48", "Custom 1kg", "100116", 1, 4.0, "N");
dtItems.Rows.Add("Allure Cafe & Co.", "f76f383f-e9f4-45c9-bb93-81102629b9c3", "2019-07-01", "2019-07-01", "2ad0667f-2254-4df5-8b24-eb36736cabb0", "6edc584b-a8eb-4f0b-a449-dbcb76a40a24", "Porter St 1Kg, RRP $40", "100111", 1, 10.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "6edc584b-a8eb-4f0b-a449-dbcb76a40a24", "Porter St 1Kg, RRP $40", "100111", 1, 30.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "51e1a867-4079-4a3c-9ddc-e93d87d80b46", "P&R Cups 12oz (1000)", "30058", 2, 12.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "401ce902-e158-4f21-85a5-3312c32457fc", "Lids 06/08/12oz (White) (1000)", "30062", 3, 7.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "9b80c825-6e9f-4f6b-9c77-f3378cc220e4", "4-Cup Cardboard Holders (300)", "41003", 4, 1.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "ea4c906e-fab1-4b15-8845-619f20e53c6a", "Organic Panela 1kg", "20014", 5, 2.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "bb3e1c10-9e67-46d3-99b4-17df45dead90", "Chocolate Powder 1Kg, RRP $25", "20034", 6, 1.0, "N");
query.Rows.Add("Aussie Bites Cafe", "30389aca-9089-4b37-9a1e-5fbc3c2af485", "2019-07-01", "2019-07-01", "85df1af6-3d1e-4e04-8fe9-d90462a59d4c", "ea89ade4-c7ff-4d79-abcd-dcdbb8122562", "X Blend 1Kg, RRP $40", "100112", 1, 4.0, "N");
query.Rows.Add("Aussie Bites Cafe", "30389aca-9089-4b37-9a1e-5fbc3c2af485", "2019-07-01", "2019-07-01", "85df1af6-3d1e-4e04-8fe9-d90462a59d4c", "21fe57ad-08f9-4c8b-81d0-d7b88b291571", "webfreight", "webfreight", 2, 1.0, "N");
query.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "6edc584b-a8eb-4f0b-a449-dbcb76a40a24", "Porter St 1Kg, RRP $40", "100111", 1, 30.0, "N");
query.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "51e1a867-4079-4a3c-9ddc-e93d87d80b46", "P&R Cups 12oz (1000)", "30058", 2, 1.0, "N");
query.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "401ce902-e158-4f21-85a5-3312c32457fc", "Lids 06/08/12oz (White) (1000)", "30062", 3, 2.0, "N");
query.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "9b80c825-6e9f-4f6b-9c77-f3378cc220e4", "4-Cup Cardboard Holders (300)", "41003", 4, 1.0, "N");
Stopwatch pullTime = new();
pullTime.Start();
BeginInvoke(new MethodInvoker(delegate
{
lblTimerAddRowEnd.Text = "Start Time,Except: " + pullTime.Elapsed.ToString("mm\\:ss\\.ff");
}));
var orderedDtItems = dtItems.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name"));
var orderedDtquery = query.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name"));
DataTable excepteditems = orderedDtItems.Except(orderedDtquery, DataRowComparer.Default).CopyToDataTable();
BeginInvoke(new MethodInvoker(delegate
{
labelControl1.Text = "End Time,Except: " + pullTime.Elapsed.ToString("mm\\:ss\\.ff");
}));
BeginInvoke(new MethodInvoker(delegate
{
dgvResults.DataSource = excepteditems;
btnStart.Enabled = true;
simpleButton1.Enabled = true;
}));
With this updater code for UI (this was threaded and used for all test comparisons):
private void timerAndUIupdate()
{
Stopwatch pullTime = new();
pullTime.Start();
do
{
Thread.Sleep(500);
BeginInvoke(new MethodInvoker(delegate
{
lblTimer.Text = "Timer: " + pullTime.Elapsed.ToString("mm\\:ss\\.ff");
Application.DoEvents();
}));
} while (btnStart.Enabled == false);
pullTime.Stop();
BeginInvoke(new MethodInvoker(delegate
{
lblTimer.Text = "Timer: " + pullTime.Elapsed.ToString("mm\\:ss\\.ff");
Application.DoEvents();
}));
}
And results on Winforms looked like this:
Then I did my janky way and the results were very fast and seemed quite accurate, and because it only took a fractions of a second I could perform this multiple times to get, New rows , Old rows not in pull that should not be deleted and Old Rows that should be Deleted -> code looked like this
dtItems.Rows.Clear();
query.Rows.Clear();
Thread start = new Thread(timerAndUIupdate);
start.Start();
dtItems.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "72421ee8-459b-46fb-bf5a-f51e80976e5a", "Pioneer 1kg (FT), RRP $42", "100115", 1, 25.0, "N");
dtItems.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "8885a911-8d32-4dfe-93e5-2e453fd54db9", "Decaf Beans 250g FT", "1002302", 2, 2.0, "N");
dtItems.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "e3aa4b15-b774-4f6a-ac21-77fa05a4332f", "P&R Cups 06oz (1000)", "30056", 3, 1.0, "N");
dtItems.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "51e1a867-4079-4a3c-9ddc-e93d87d80b46", "P&R Cups 12oz (1000)", "30058", 4, 1.0, "N");
query.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "72421ee8-459b-46fb-bf5a-f51e80976e5a", "Pioneer 1kg (FT), RRP $42", "100115", 1, 25.0, "N");
query.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "8885a911-8d32-4dfe-93e5-2e453fd54db9", "Decaf Beans 250g FT", "1002302", 2, 2.0, "N");
query.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "e3aa4b15-b774-4f6a-ac21-77fa05a4332f", "P&R Cups 06oz (1000)", "30056", 3, 1.0, "N");
query.Rows.Add("4 Beans Cafe", "2af0f4bf-52ea-44fb-b1b3-36181fe7bfdf", "2019-07-01", "2019-07-01", "7fc4f98a-35af-4da3-afe3-f7cfcd922ea7", "51e1a867-4079-4a3c-9ddc-e93d87d80b46", "P&R Cups 12oz (1000)", "30058", 4, 1.0, "N");
for (int i = 1; i < 100000; i++)
{
dtItems.Rows.Add("Bennett St Dairy", "ed0c8d30-6469-4e13-af5a-36d7357a4a70", "2019-07-01", "2019-07-01", "8b909a4b-a07b-4a06-bebc-6a3387433aaf", "c8cc1115-da02-42cf-b427-accc1b6d07e3", "Trailblazer 1Kg, RRP $44", "10011", i, (i * 4), "N");
query.Rows.Add("Bennett St Dairy", "ed0c8d30-6469-4e13-af5a-36d7357a4a70", "2019-07-01", "2019-07-01", "8b909a4b-a07b-4a06-bebc-6a3387433aaf", "c8cc1115-da02-42cf-b427-accc1b6d07e3", "Trailblazer 1Kg, RRP $44", "10011", i, (i * 4), "N");
}
dtItems.Rows.Add("Air Coffee International Cafe Pty Ltd", "bb4fa724-9759-4c60-93fe-70fbdfd00417", "2019-07-01", "2019-07-01", "b972f020-3740-4ef2-941f-78b1a9edefa8", "0be54733-ac0e-43f9-8ea5-204c7cdb5f48", "Custom 1kg", "100116", 1, 4.0, "N");
dtItems.Rows.Add("Allure Cafe & Co.", "f76f383f-e9f4-45c9-bb93-81102629b9c3", "2019-07-01", "2019-07-01", "2ad0667f-2254-4df5-8b24-eb36736cabb0", "6edc584b-a8eb-4f0b-a449-dbcb76a40a24", "Porter St 1Kg, RRP $40", "100111", 1, 10.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "6edc584b-a8eb-4f0b-a449-dbcb76a40a24", "Porter St 1Kg, RRP $40", "100111", 1, 30.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "51e1a867-4079-4a3c-9ddc-e93d87d80b46", "P&R Cups 12oz (1000)", "30058", 2, 12.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "401ce902-e158-4f21-85a5-3312c32457fc", "Lids 06/08/12oz (White) (1000)", "30062", 3, 7.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "9b80c825-6e9f-4f6b-9c77-f3378cc220e4", "4-Cup Cardboard Holders (300)", "41003", 4, 1.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "ea4c906e-fab1-4b15-8845-619f20e53c6a", "Organic Panela 1kg", "20014", 5, 2.0, "N");
dtItems.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "bb3e1c10-9e67-46d3-99b4-17df45dead90", "Chocolate Powder 1Kg, RRP $25", "20034", 6, 1.0, "N");
query.Rows.Add("Aussie Bites Cafe", "30389aca-9089-4b37-9a1e-5fbc3c2af485", "2019-07-01", "2019-07-01", "85df1af6-3d1e-4e04-8fe9-d90462a59d4c", "ea89ade4-c7ff-4d79-abcd-dcdbb8122562", "X Blend 1Kg, RRP $40", "100112", 1, 4.0, "N");
query.Rows.Add("Aussie Bites Cafe", "30389aca-9089-4b37-9a1e-5fbc3c2af485", "2019-07-01", "2019-07-01", "85df1af6-3d1e-4e04-8fe9-d90462a59d4c", "21fe57ad-08f9-4c8b-81d0-d7b88b291571", "webfreight", "webfreight", 2, 1.0, "N");
query.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "6edc584b-a8eb-4f0b-a449-dbcb76a40a24", "Porter St 1Kg, RRP $40", "100111", 1, 30.0, "N");
query.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "51e1a867-4079-4a3c-9ddc-e93d87d80b46", "P&R Cups 12oz (1000)", "30058", 2, 1.0, "N");
query.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "401ce902-e158-4f21-85a5-3312c32457fc", "Lids 06/08/12oz (White) (1000)", "30062", 3, 2.0, "N");
query.Rows.Add("Mad Hatter Wine Co", "49340e5f-c7ef-41d9-9f1b-200711e6e629", "2021-07-28", "2021-07-28", "e16cbbac-c319-45f3-ac53-89d979fbcdc1", "9b80c825-6e9f-4f6b-9c77-f3378cc220e4", "4-Cup Cardboard Holders (300)", "41003", 4, 1.0, "N");
Stopwatch pullTime = new();
pullTime.Start();
BeginInvoke(new MethodInvoker(delegate
{
lblTimerAddRowEnd.Text = "Start Time,Except: " + pullTime.Elapsed.ToString("mm\\:ss\\.ff");
}));
var orderedDtItems = dtItems.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name"));
var orderedDtquery = query.AsEnumerable().OrderBy(row => Convert.ToDateTime(row.Field("Date"))).ThenBy(row => row.Field("Name"));
dtOnlyNewRows.Rows.Clear();
HashSet orderedDtItemsHS = new();
HashSet orderedDtqueryHS = new();
HashSet orderedDtItemsHSRemains = new();
HashSet orderedDtqueryHSRemains = new();
foreach (DataRow dr in orderedDtquery)
{
orderedDtqueryHSRemains.Add(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
orderedDtqueryHS.Add(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
}
foreach (DataRow dr in orderedDtItems)
{
orderedDtItemsHSRemains.Add(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
orderedDtItemsHS.Add(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
bool added = orderedDtqueryHSRemains.Add(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
if (added == false)
{
orderedDtqueryHSRemains.Remove(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
}
else if (added == true)
{
dtOnlyNewRows.ImportRow(dr);
orderedDtqueryHSRemains.Remove(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
}
}
foreach (DataRow dr in orderedDtquery)
{
bool added = orderedDtItemsHSRemains.Add(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
if (added == false)
{
orderedDtItemsHSRemains.Remove(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
}
else if (added == true)
{
DateTime rowTime = Convert.ToDateTime(dr["date"].ToString());
if (rowTime <= MonthCutOff)
{
dtOnlyLeftoverRows.ImportRow(dr);
}
else
{
dtOnlyDeleteRows.ImportRow(dr);
}
orderedDtItemsHSRemains.Remove(dr["CardRecordID"].ToString() + "⌁" + dr["Date"].ToString() + "⌁" + dr["SaleID"].ToString() + "⌁" + dr["ItemID"].ToString()
+ "⌁" + dr["LineNumber"].ToString() + "⌁" + dr["Quantity"].ToString());
}
}
Debug.WriteLine(dtOnlyNewRows.Rows.Count.ToString());
BeginInvoke(new MethodInvoker(delegate
{
labelControl1.Text = "End Time,Except: " + pullTime.Elapsed.ToString("mm\\:ss\\.ff");
}));
pullTime.Stop();
BeginInvoke(new MethodInvoker(delegate
{
dgvRowsRemaing.DataSource = dtOnlyLeftoverRows;
dgvResults.DataSource = dtOnlyNewRows;
dgvDeleteRows.DataSource = dtOnlyDeleteRows;
btnStart.Enabled = true;
}));
And the end result looked as follows:
After all this explanation comes my questions:
- What did I do wrong in the other methods, can they be made faster?
- How should I compare Datatables, if my janky methods is not OK?
- As long as it works and is fast even if janky, is it OK?
- What are the possible problems with my janky method?
Edited: 2021-08-03 11:25 PM AEST(Australian Eastern Standard Time)
the Code Juris wrote is Neater and Much Quicker, What it looks like when applied to my dummy data Windows Forms
3 x quicker , less messy code, way shorter this was exactly what I was looking for thank you
ANSWER
Answered 2021-Aug-03 at 09:59I'd do this by indexing the datatables with a pair of dictionaries. DataTable can have primary keys defined and perform fast lookups that use dictionaries internally but in general working with datatables is pretty ugly stuff so no point adding to it with more PK ugly
So we have some datatable on the right, and it's downlaoded from a DB, and you have decided that the "Foo" and "Bar" columns are the PK. Foo is a string, Bar is an int:
Dim rIndex = new Dictionary(Of (ValueTuple(Of String, Integer), DataRow)
For Each r as DataRow In rightDt.Rows
Dim key = ( r.Field(Of String)("Foo"), r.Field(Of Integer)("Bar") )
rIndex(key) = r
Next r
And we have some file that's been read into the left datatable. The file's columns happen to be called Wit (string) and Woo (int)
Dim lIndex = new Dictionary(Of (ValueTuple(Of String, Integer), DataRow)
For Each r as DataRow In leftDt.Rows
Dim key = (r.Field(Of String)("Wit"), r.Field(Of Integer)("Woo") )
lIndex(key) = r
Next r
Now it's probably going to make life easy if we stash the keys into a hashset too as we go; this represents the union of the left and the right
Dim allKeys as New HashSet(Of ValueTuple(Of String, Integer))
Dim rIndex = new Dictionary(Of (ValueTuple(Of String, Integer), DataRow)
For Each r as DataRow In rightDt.Rows
Dim key = ( r.Field(Of String)("Foo"), r.Field(Of Integer)("Bar") )
rIndex(key) = r
allKeys.Add(key)
Next r
Dim lIndex = new Dictionary(Of (ValueTuple(Of String, Integer), DataRow)
For Each r as DataRow In leftDt.Rows
Dim key = (r.Field(Of String)("Wit"), r.Field(Of Integer)("Woo") )
lIndex(key) = r
allKeys.Add(key)
Next r
All that remains is to enumerate the allKeys and ask the dictionaries whether they contain it or not and decide what to do
For Each k in allKeys
Dim inL = lIndex.ContainsKey(k)
Dim inR = rIndex.ContainsKey(k)
If inL AndAlso inR Then
Dim updateRo = lIndex(k) 'update the db using this datarow
...
ElseIf inL Then
Dim insertRo = lIndex(k) 'insert this row to the db
...
Else
Dim deleteRo = rIndex(k) 'delete this row from the db
...
End If
Next k
--
Hah, just realized my brain is still in VB mode. Here's the C# version of the above:
var allKeys = new HashSet<(string, int)>();
var rIndex = new Dictionary<(string, int), DataRow>();
foreach(DataRow r in rightDt.Rows){
var key = (r.Field("Foo"), r.Field("Bar"));
rIndex[key] = r;
allKeys.Add(key);
}
var lIndex = new Dictionary<(string, int), DataRow>();
foreach(DataRow r in leftDt.Rows){
var key = (r.Field("Wit"), r.Field("Woo"));
lIndex[key] = r;
allKeys.Add(key);
}
foreach(var k in allKeys){
var inL = lIndex.ContainsKey(k);
var inR = rIndex.ContainsKey(k);
if(inL && inR){
var updateRo = lIndex[k]; //update the db using this datarow
...
} else if(inL){
var insertRo = lIndex[k]; //insert this row to the db
...
} else {
var deleteRo = rIndex[k]; //delete this row from the db
...
}
}
You can see a working sample at https://dotnetfiddle.net/3jfrPl
QUESTION
I am looking for a solution to my problem I have a relation => Company
has_many Councils
, through CouncilCompany
.
And I would like to display Company in context of given Council, so if CouncilCompany
has name
property present display it over default Company
name
.
# == Schema Information
#
# Table name: council_companies
#
# id :uuid not null, primary key
# name :string
# == Schema Information
#
# Table name: companies
#
# id :uuid not null, primary key
# name :string default(FALSE), not null
render json: Company::Representer::Show.new(@company).to_json(
current_user: current_api_v1_user,
council: @council
)
require 'representable/json'
module Company::Representer
class Show < Representable::Decorator
include Representable::JSON
Company.columns_hash.keys.each do |column|
property column.to_sym.as_json, render_nil: true
end
end
end
What would be the best way to do that? Tried already to find solution here: https://trailblazer.to/2.1/docs/representable.html#representable-api
ANSWER
Answered 2021-Jun-12 at 16:23How about defining a representer for CouncilCompany
instead, as it belongs to Company
?
require 'representable/json'
module CouncilCompany::Representer
class Show < Representable::Decorator
include Representable::JSON
property :name, default: -> { company.name }
property :company do
property :id
property :name
...
end
end
end
render json: CouncilCompany::Representer::Show.new(@council_company).to_json(
current_user: current_api_v1_user
)
QUESTION
I am trying to create a registration form with Trailblazer and validation setup using Dry-Validation. I hit a snag which seems to be related to virtual fields. My contract looks like this.
module User::Contract
class Register < Reform::Form
model :user
property :first_name
property :last_name
property :password, virtual: true
property :password_confirmation, virtual: true
property :email
property :phone
property :bio
validation do
option :form
params do
required(:first_name).filled(:string)
required(:last_name).filled(:string)
required(:email).filled(:string)
required(:phone).filled(:string)
end
rule(:email) do
unless /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i.match?(value)
key.failure('has invalid format')
end
end
rule(:password) do
key.failure('does not match') if value != form.password_confirmation
key.failure('too short') if value.length < 7
end
end
end
end
When I run it in the terminal i get this:
contract = User::Contract::Register.new(User.new)
contract.valid?
Dry::Validation::InvalidKeysError (.rule specifies keys that are not defined by the schema: [:password])
Looks like the issue I am getting is because its a virtual field and because using Dry-Validation. I tried commenting the internal code and still had the issue. How do I validate a virtual field?
Any advice highly appreciated.
ANSWER
Answered 2021-Apr-18 at 14:54Yogesh Khater from Trailblazer Zulip Chat was kind enough to point out the error for me.
When we need to define a rule for a virtual field, we need to make sure that the property is required. This is a requirement in the dry-validation
library.
The above can be fixed by requiring the property.
class Register < Reform::Form
model :user
property :password, virtual: true
property :password_confirmation, virtual: true
# ....
validation do
option :form
params do
# ...
required(:password).filled(:string)
end
rule(:password) do
# ...
end
end
end
QUESTION
I am building a webapp where I have different sticky elements in a flexbox that is scrollable.
In the middle container of the flexbox you can scroll through content that is contained in a new div starting at the header/bottom of the other div. The problem is that I need the div-container for the content to resize responsively according to the viewport. Currently, it is not, the content container is always 100vh, even if the image does not fill up the whole viewport.
How do I make it so the container div's height is not bigger than the image height? I can't get it working without making the sticky functions breaking.
You can see what I mean in the jsfidle here (it is the white space between the next header in the scroll that i want to remove): https://jsfiddle.net/4w1kjz76/
:root {
/* Variables for header h1*/
--ratio: 15;
--reverse-ratio: 20;
--container-width: 50w;
--container-height: 12.5vh;
--font1-sizeVW: 19vh;
--font1-sizeVH: calc(var(--ratio) * 15vw);
--font2-sizeVW: 6vh;
--font2-sizeVH: calc(var(--ratio) * 6vw);
}
html, body {
margin:0;
padding:0;
-ms-overflow-style: none;
/* IE and Edge */
}
body::-webkit-scrollbar {
display: none;
}
@media(max-width:50em) {
.section {
flex-direction:column
}
}
* {
box-sizing: border-box;
}
main {
max-width: 100vw;
margin: 0px auto;
display: flex;
flex-flow: row wrap;
}
.contentmain {
height: auto;
display: block;
padding: 0px;
flex: 1 1 50%;
}
.sidebarright {
background-color: green;
color: white;
padding: 20px;
height: 100vh;
top: 0;
width: 5%;
position: sticky;
align-self: flex-start;
}
.sidebarleft {
background-color: blue;
height: 100vh;
padding: 20px;
display: inline-block;
flex: 1 1 20%;
top: 0;
position: sticky;
align-self: flex-start;
color: white;
}
h1 {
top:-4.4vh;
color: white;
font-family: arial;
}
.content {
position: relative;
border: 0px solid red;
height: 100vh;
top: 0;
text-align: left;
color: black;
}
.content img {
float: left;
height: auto;
width: 49.75%;
}
.rightimg {
margin-left: 0.5%;
}
.header {
position: sticky;
top: 0;
margin:0;
padding:0;
background-color:black;
height:12.5vh;
}
.bottommenu {
background: orange;
color: white;
width: 100%;
padding: 20px;
height: 9vh;
position:sticky;
bottom:0;
right:0;
}
TRAILBLAZER
LEFT-BAR
HEADER 1
HEADER 2
HEADER 3
HEADER 3
HEADER 4
STICKY BOTTOM MENU
RIGHT-BAR
ANSWER
Answered 2021-Jan-11 at 12:20This space is coming from h1
, easily add margin-top: 0;
:root {
/* Variables for header h1*/
--ratio: 15;
--reverse-ratio: 20;
--container-width: 50w;
--container-height: 12.5vh;
--font1-sizeVW: 19vh;
--font1-sizeVH: calc(var(--ratio) * 15vw);
--font2-sizeVW: 6vh;
--font2-sizeVH: calc(var(--ratio) * 6vw);
}
html, body {
margin:0;
padding:0;
-ms-overflow-style: none;
/* IE and Edge */
}
body::-webkit-scrollbar {
display: none;
}
@media(max-width:50em) {
.section {
flex-direction:column
}
}
* {
box-sizing: border-box;
}
main {
max-width: 100vw;
margin: 0px auto;
display: flex;
flex-flow: row wrap;
}
.contentmain {
height: auto;
display: block;
padding: 0px;
flex: 1 1 50%;
}
.sidebarright {
background-color: green;
color: white;
padding: 20px;
height: 100vh;
top: 0;
width: 5%;
position: sticky;
align-self: flex-start;
}
.sidebarleft {
background-color: blue;
height: 100vh;
padding: 20px;
display: inline-block;
flex: 1 1 20%;
top: 0;
position: sticky;
align-self: flex-start;
color: white;
}
h1 {
top:-4.4vh;
color: white;
font-family: arial;
margin-top: 0;
}
.content {
position: relative;
border: 0px solid red;
height: 100vh;
top: 0;
text-align: left;
color: black;
}
.content img {
float: left;
height: auto;
width: 49.75%;
}
.rightimg {
margin-left: 0.5%;
}
.header {
position: sticky;
top: 0;
margin:0;
padding:0;
background-color:black;
height:12.5vh;
}
.bottommenu {
background: orange;
color: white;
width: 100%;
padding: 20px;
height: 9vh;
position:sticky;
bottom:0;
right:0;
}
TRAILBLAZER
LEFT-BAR
HEADER 1
HEADER 2
HEADER 3
HEADER 3
HEADER 4
STICKY BOTTOM MENU
RIGHT-BAR
QUESTION
I'm trying to create a dropdown menu for one of the items in my nav bar. I based the code on this W3Schools example. Upon hover, the menu appears below the nav bar (as it should be) but it is 1) stacked horizontally rather than vertically and 2) appears to the far right on the page. I've look at similar questions here but haven't been able to figure out the problem in my code. Any help would be appreciated.
/* nav */
nav {
display: flex;
flex-wrap: wrap;
padding: .25rem 0;
color: #ffffff;
font: 30px 'Roboto', sans-serif;
margin: auto;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
overflow: hidden;
}
nav a {
display: block;
margin: 0 40px;
}
/* dropdown container */
.dropdown {
float: none;
position: relative;
overflow: visibile;
}
/* dropdown button */
.dropdown .dropbtn {
display: flex;
font-size: 30px;
border: none;
outline: none;
color: #ffffff;
padding: inherit;
background-color: inherit;
font-family: inherit;
margin: auto;
}
/* dropdown content (hidden by default */
.dropdown-content {
display: none;
position: absolute;
margin-top: 10px;
background-color: #ffffff;
width: 250px;
left: calc(50% - 125px);
}
.dropdown-content>a {
color: black;
text-align: left;
border-bottom: 1px solid #009EDB;
}
/* show dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
float: left;
margin: 0;
}
ANSWER
Answered 2020-Nov-28 at 02:43Your dropdown is structured of anchors (links, tags), which naturally are inline elements. That means that naturally these elements are located as part of page or line flow. To make them appear vertical, you need to change them to be "block" elements, which you use by adding
display: block
to the styling on the dropdown a
elements:
nav a {
margin: 0 40px;
display: block;
}
The 'margin' was already present in this particular element.
I've also removed all the "!important
" from your styling because it's bad practice and wasn't helping at all. Since you're missing a background, I restyled the triggering element to have red text so it doesn't seem like a random white space was triggering the dropdown.
That being said, I don't see any "styled far right" behavior for the drop down. The menu is displayed directly under the triggering element (with a 40px margin, which if you have a really small screen might make it seem like it's super far right.)
/* nav */
nav {
display: flex;
flex-wrap: wrap;
padding: .25rem 0;
color: #ffffff;
font: 30px 'Roboto', sans-serif;
margin: auto;
justify-content: center;
overflow: hidden;
}
nav a {
margin: 0 40px;
display: block;
}
/* dropdown container */
.dropdown {
float: none;
overflow: hidden;
}
/* dropdown button */
.dropdown .dropbtn {
display: flex;
font-size: 30px;
border: none;
outline: none;
color: red;
padding: inherit;
background-color: inherit;
font-family: inherit;
margin: auto;
}
/* dropdown content (hidden by default */
.dropdown-content {
display: none;
position: absolute;
background-color: inherit;
width: 100%;
}
/* show dropdown menu on hover */
.dropdown:hover .dropdown-content {
display: block;
}
Community Discussions, Code Snippets contain sources that include Stack Exchange Network
Vulnerabilities
No vulnerabilities reported
Install trailblazer
Support
Find, review, and download reusable Libraries, Code Snippets, Cloud APIs from over 650 million Knowledge Items
Find more librariesExplore Kits - Develop, implement, customize Projects, Custom Functions and Applications with kandi kits
Save this library and start creating your kit
Share this Page